integrate librte_ipsec SAD into ipsec-secgw
cover integrate librte_ipsec SAD into ipsec-secgw
This series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's.
Vladimir Medvedkin (4):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation
examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 13 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/sa.c | 236 +++++++++++++++++++------------------ examples/ipsec-secgw/sad.c | 90 ++++++++++++++ examples/ipsec-secgw/sad.h | 74 ++++++++++++ examples/ipsec-secgw/sp4.c | 24 ++-- examples/ipsec-secgw/sp6.c | 24 ++-- lib/librte_ipsec/ipsec_sad.c | 20 ++-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 11 files changed, 344 insertions(+), 146 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
Signature · 1 line
2.7.4
PATCH 1/4 ipsec: move ipsec sad name length into .h
Move IPSEC_SAD_NAMESIZE into public header
and rename it to RTE_IPSEC_SAD_NAMESIZE
--- lib/librte_ipsec/ipsec_sad.c | 20 ++++++++++---------- lib/librte_ipsec/rte_ipsec_sad.h | 2 ++ 2 files changed, 12 insertions(+), 10 deletions(-)
lib/librte_ipsec/ipsec_sad.c +10 -10
@@ -20,7 +20,6 @@* 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>" */ #define SAD_FORMAT SAD_PREFIX "%s"
@@ -34,7 +33,7 @@ struct hash_cnt { };struct rte_ipsec_sad { -char name[IPSEC_SAD_NAMESIZE ]; +char name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_hash *hash[RTE_IPSEC_SAD_KEY_TYPE_MASK ];/* Array to track number of more specific rules * (spi_dip or spi_dip_sip). Used only in add/delete
@@ -231,7 +230,7 @@ struct rte_ipsec_sad * rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf) { char hash_name[RTE_HASH_NAMESIZE]; -char sad_name[IPSEC_SAD_NAMESIZE ]; +char sad_name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_tailq_entry *te;struct rte_ipsec_sad_list *sad_list;struct rte_ipsec_sad *sad, *tmp_sad =NULL ;
@@ -249,8 +248,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)return NULL ; } - ret =snprintf (sad_name,IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); -if (ret <0 || ret >=IPSEC_SAD_NAMESIZE ) { + ret =snprintf (sad_name,RTE_IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); +if (ret <0 || ret >=RTE_IPSEC_SAD_NAMESIZE ) { rte_errno =ENAMETOOLONG ;return NULL ; }
@@ -326,7 +325,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)/* guarantee there's no existing */ TAILQ_FOREACH(te, sad_list, next) { tmp_sad = (struct rte_ipsec_sad *)te->data; -if (strncmp (sad_name, tmp_sad->name,IPSEC_SAD_NAMESIZE ) ==0 ) +if (strncmp (sad_name, tmp_sad->name, +RTE_IPSEC_SAD_NAMESIZE ) ==0 )break ; }if (te !=NULL ) {
@@ -354,14 +354,14 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)struct rte_ipsec_sad *rte_ipsec_sad_find_existing (const char *name) { -char sad_name[IPSEC_SAD_NAMESIZE ]; +char sad_name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_ipsec_sad *sad =NULL ;struct rte_tailq_entry *te;struct rte_ipsec_sad_list *sad_list;int ret; - ret =snprintf (sad_name,IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); -if (ret <0 || ret >=IPSEC_SAD_NAMESIZE ) { + ret =snprintf (sad_name,RTE_IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); +if (ret <0 || ret >=RTE_IPSEC_SAD_NAMESIZE ) { rte_errno =ENAMETOOLONG ;return NULL ; }
@@ -372,7 +372,7 @@ rte_ipsec_sad_find_existing(const char *name)rte_mcfg_tailq_read_lock (); TAILQ_FOREACH(te, sad_list, next) { sad = (struct rte_ipsec_sad *) te->data; -if (strncmp (sad_name, sad->name,IPSEC_SAD_NAMESIZE ) ==0 ) +if (strncmp (sad_name, sad->name,RTE_IPSEC_SAD_NAMESIZE ) ==0 )break ; }rte_mcfg_tailq_read_unlock ();
lib/librte_ipsec/rte_ipsec_sad.h +2 -0
@@ -47,6 +47,8 @@ union rte_ipsec_sad_key {struct rte_ipsec_sadv6_key v6; }; +/** Max number of characters in SAD name. */ +#define RTE_IPSEC_SAD_NAMESIZE 64/** Flag to create SAD with ipv6 dip and sip addresses */ #define RTE_IPSEC_SAD_FLAG_IPV6 0x1/** Flag to support reader writer concurrency */
Signature · 1 line
2.7.4
PATCH 2/4 examples/ipsec-secgw: implement inbound SAD
In reply to Vladimir MedvedkinAdd initial support for librte_ipsec SAD library
--- examples/ipsec-secgw/ipsec.h | 11 ++++++ examples/ipsec-secgw/sad.c | 90 ++++++++++++++++++++++++++++++++++++++++++++ examples/ipsec-secgw/sad.h | 74 ++++++++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
examples/ipsec-secgw/ipsec.h +11 -0
@@ -53,6 +53,17 @@ struct ipsec_xform;struct rte_mbuf ;struct ipsec_sa ; +/* +* Keeps number of configured SA's of each type: +* transport +* v4 tunnel +* v6 tunnel +*/ +struct ipsec_sa_cnt { +uint32_t nb_trn; +uint32_t nb_v4_tun; +uint32_t nb_v6_tun; +};typedef int32_t (*ipsec_xform_fn )(struct rte_mbuf *m,struct ipsec_sa *sa,struct rte_crypto_op *cop);
examples/ipsec-secgw/sad.c new file +90 -0
90 lines not on this page · raw message
examples/ipsec-secgw/sad.h new file +74 -0
74 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH 3/4 examples/ipsec-secgw: integrate inbound SAD
In reply to Vladimir MedvedkinIntegrate ipsec SAD support into secgw app:
1. Use SAD library for inbound SA lookup
2. Changes in struct sa_ctx:
- sa array allocates dynamically depending on number of configured sa
- All SA's are kept one by one without using SPI2IDX
3. SP's userdata now contain index of SA in sa_ctx instead of SPI
4. Get rid of SPI2IDX macro
--- examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 2 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/sa.c | 160 +++++++++++++++++-------------------- examples/ipsec-secgw/sp4.c | 24 +++--- examples/ipsec-secgw/sp6.c | 24 +++--- 7 files changed, 110 insertions(+), 107 deletions(-)
examples/ipsec-secgw/Makefile +1 -0
@@ -12,6 +12,7 @@ SRCS-y += esp.c SRCS-y += sp4.c SRCS-y += sp6.c SRCS-y += sa.c +SRCS-y += sad.c SRCS-y += rt.c SRCS-y += ipsec_process.c SRCS-y += ipsec-secgw.c
examples/ipsec-secgw/ipsec-secgw.c +2 -2
@@ -601,7 +601,7 @@ inbound_sp_sa(struct sp_ctx *sp, struct sa_ctx *sa, struct traffic_type *ip,continue ; } - sa_idx =SPI2IDX (res); + sa_idx = res -1 ;if (!inbound_sa_check (sa, m, sa_idx)) {rte_pktmbuf_free (m);continue ;
@@ -688,7 +688,7 @@ outbound_sp(struct sp_ctx *sp, struct traffic_type *ip, j =0 ;for (i =0 ; i < ip->num; i++) { m = ip->pkts[i]; - sa_idx =SPI2IDX (ip->res[i]); + sa_idx = ip->res[i] -1 ;if (ip->res[i] ==DISCARD )rte_pktmbuf_free (m);else if (ip->res[i] ==BYPASS )
examples/ipsec-secgw/ipsec.h +1 -1
@@ -363,7 +363,7 @@ sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],* or -ENOENT otherwise. */ int -sa_spi_present (uint32_t spi,int inbound); +sa_spi_present (struct sa_ctx *sa_ctx,uint32_t spi,int inbound);void sa_init (struct socket_ctx *ctx,int32_t socket_id);
examples/ipsec-secgw/meson.build +1 -1
@@ -10,5 +10,5 @@ deps += ['security', 'lpm', 'acl', 'hash', 'ip_frag', 'ipsec'] allow_experimental_apis = true sources = files( 'esp.c', 'ipsec.c', 'ipsec_process.c', 'ipsec-secgw.c', - 'parser.c', 'rt.c', 'sa.c', 'sp4.c', 'sp6.c' + 'parser.c', 'rt.c', 'sa.c', 'sad.c', 'sp4.c', 'sp6.c' )
examples/ipsec-secgw/sa.c +75 -85
311 lines not on this page · raw message
examples/ipsec-secgw/sp4.c +15 -9
@@ -493,10 +493,11 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules,* check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value (int inbound) +check_spi_value (struct sa_ctx *sa_ctx,int inbound) {uint32_t i, num, spi; -const struct acl4_rules *acr; +int32_t spi_idx; +struct acl4_rules *acr;if (inbound !=0 ) { acr = acl4_rules_in;
@@ -508,11 +509,16 @@ check_spi_value(int inbound)for (i =0 ; i != num; i++) { spi = acr[i].data.userdata; -if (spi !=DISCARD && spi !=BYPASS && -sa_spi_present (spi, inbound) <0 ) { -RTE_LOG (ERR ,IPSEC ,"SPI %u is not present in SAD\n" , - spi); -return -ENOENT ; +if (spi !=DISCARD && spi !=BYPASS ) { + spi_idx =sa_spi_present (sa_ctx, spi, inbound); +if (spi_idx <0 ) { +RTE_LOG (ERR ,IPSEC , +"SPI %u is not present in SAD\n" , + spi); +return -ENOENT ; + } +/* Update userdata with spi index */ + acr[i].data.userdata = spi_idx +1 ; } }
@@ -535,11 +541,11 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id)rte_exit (EXIT_FAILURE ,"Outbound SP DB for socket %u already " "initialized\n" , socket_id); -if (check_spi_value (1 ) <0 ) +if (check_spi_value (ctx->sa_in,1 ) <0 )rte_exit (EXIT_FAILURE ,"Inbound IPv4 SP DB has unmatched in SAD SPIs\n" ); -if (check_spi_value (0 ) <0 ) +if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv4 SP DB has unmatched in SAD SPIs\n" );
examples/ipsec-secgw/sp6.c +15 -9
@@ -625,10 +625,11 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_rules *rules,* check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value (int inbound) +check_spi_value (struct sa_ctx *sa_ctx,int inbound) {uint32_t i, num, spi; -const struct acl6_rules *acr; +int32_t spi_idx; +struct acl6_rules *acr;if (inbound !=0 ) { acr = acl6_rules_in;
@@ -640,11 +641,16 @@ check_spi_value(int inbound)for (i =0 ; i != num; i++) { spi = acr[i].data.userdata; -if (spi !=DISCARD && spi !=BYPASS && -sa_spi_present (spi, inbound) <0 ) { -RTE_LOG (ERR ,IPSEC ,"SPI %u is not present in SAD\n" , - spi); -return -ENOENT ; +if (spi !=DISCARD && spi !=BYPASS ) { + spi_idx =sa_spi_present (sa_ctx, spi, inbound); +if (spi_idx <0 ) { +RTE_LOG (ERR ,IPSEC , +"SPI %u is not present in SAD\n" , + spi); +return -ENOENT ; + } +/* Update userdata with spi index */ + acr[i].data.userdata = spi_idx +1 ; } }
@@ -667,11 +673,11 @@ sp6_init(struct socket_ctx *ctx, int32_t socket_id)rte_exit (EXIT_FAILURE ,"Outbound IPv6 SP DB for socket %u " "already initialized\n" , socket_id); -if (check_spi_value (1 ) <0 ) +if (check_spi_value (ctx->sa_in,1 ) <0 )rte_exit (EXIT_FAILURE ,"Inbound IPv6 SP DB has unmatched in SAD SPIs\n" ); -if (check_spi_value (0 ) <0 ) +if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv6 SP DB has unmatched in SAD SPIs\n" );
Signature · 1 line
2.7.4
PATCH 4/4 examples/ipsec-secgw: get rid of maximum sa limitation
In reply to Vladimir MedvedkinParse config file and save SA's into linked list
instead of flat array with predefined size.
--- examples/ipsec-secgw/sa.c | 78 +++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 30 deletions(-)
examples/ipsec-secgw/sa.c +48 -30
@@ -20,6 +20,7 @@#include <rte_random.h> #include <rte_ethdev.h> #include <rte_malloc.h> +#include <sys/queue.h> #include "ipsec.h" #include "esp.h"
@@ -133,11 +134,17 @@ const struct supported_aead_algo aead_algos[] = { } }; -static struct ipsec_sa sa_out[IPSEC_SA_MAX_ENTRIES ]; +struct ipsec_sa_mgmt { +STAILQ_ENTRY (ipsec_sa_mgmt) next; +struct ipsec_sa sa; +}; +STAILQ_HEAD (sa_head, ipsec_sa_mgmt); + +static struct sa_head sa_out_head =STAILQ_HEAD_INITIALIZER (sa_out_head);static uint32_t nb_sa_out;static struct ipsec_sa_cnt sa_out_cnt; -static struct ipsec_sa sa_in[IPSEC_SA_MAX_ENTRIES ]; +static struct sa_head sa_in_head =STAILQ_HEAD_INITIALIZER (sa_in_head);static uint32_t nb_sa_in;static struct ipsec_sa_cnt sa_in_cnt;
@@ -228,6 +235,8 @@ void parse_sa_tokens(char **tokens, uint32_t n_tokens, struct parse_status *status) { +struct ipsec_sa_mgmt *sa_mgmt; +struct sa_head *head;struct ipsec_sa *rule =NULL ;struct rte_ipsec_session *ips;uint32_t ti;/*token index*/
@@ -243,27 +252,21 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,uint32_t portid_p =0 ;uint32_t fallback_p =0 ; + sa_mgmt =calloc (1 ,sizeof (struct ipsec_sa_mgmt )); +if (sa_mgmt ==NULL ) +return ; + + rule = &sa_mgmt->sa; +if (strcmp (tokens[0 ],"in" ) ==0 ) { ri = &nb_sa_in; sa_cnt = &sa_in_cnt; - -APP_CHECK (*ri <=IPSEC_SA_MAX_ENTRIES -1 , status, -"too many sa rules, abort insertion\n" ); -if (status->status <0 ) -return ; - - rule = &sa_in[*ri]; + head = &sa_in_head; rule->direction =RTE_SECURITY_IPSEC_SA_DIR_INGRESS ; }else { ri = &nb_sa_out; sa_cnt = &sa_out_cnt; - -APP_CHECK (*ri <=IPSEC_SA_MAX_ENTRIES -1 , status, -"too many sa rules, abort insertion\n" ); -if (status->status <0 ) -return ; - - rule = &sa_out[*ri]; + head = &sa_out_head; rule->direction =RTE_SECURITY_IPSEC_SA_DIR_EGRESS ; }
@@ -687,6 +690,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, rule->portid =-1 ; } +STAILQ_INSERT_TAIL (head, sa_mgmt, next); *ri = *ri +1 ; }
@@ -956,12 +960,13 @@ sa_add_address_inline_crypto(struct ipsec_sa *sa) }static int -sa_add_rules (struct sa_ctx *sa_ctx,const struct ipsec_sa entries[], +sa_add_rules (struct sa_ctx *sa_ctx,struct sa_head *entries,uint32_t nb_entries,uint32_t inbound,struct socket_ctx *skt_ctx) { +struct ipsec_sa_mgmt *sa_mgmt;struct ipsec_sa *sa; -uint32_t i, idx; +uint32_t idx;uint16_t iv_length, aad_length;int inline_status;int32_t rc;
@@ -970,15 +975,18 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],/* for ESN upper 32 bits of SQN also need to be part of AAD */ aad_length = (app_sa_prm.enable_esn !=0 ) ?sizeof (uint32_t ) :0 ; -for (i =0 ; i < nb_entries; i++) { - idx = i; + sa_mgmt =STAILQ_FIRST (entries); +for (idx =0 ; idx < nb_entries; idx++) { +if (sa_mgmt ==NULL ) +rte_exit (EXIT_FAILURE ,"SA mgmt queue is broken\n" ); + sa = &sa_ctx->sa[idx];if (sa->spi !=0 ) {printf ("Index %u already in use by SPI %u\n" , idx, sa->spi);return -EINVAL ; } - *sa = entries[i]; + *sa = sa_mgmt->sa;if (inbound) { rc =ipsec_sad_add (&sa_ctx->sad, sa);
@@ -1114,20 +1122,29 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],print_one_sa_rule (sa, inbound); } + sa_mgmt =STAILQ_NEXT (sa_mgmt, next); } +for (sa_mgmt =STAILQ_FIRST (entries); sa_mgmt !=NULL ; + sa_mgmt =STAILQ_FIRST (entries)) { +STAILQ_REMOVE_HEAD (entries, next); +free (sa_mgmt); + } + +STAILQ_INIT (entries); +return 0 ; }static inline int -sa_out_add_rules (struct sa_ctx *sa_ctx,const struct ipsec_sa entries[], +sa_out_add_rules (struct sa_ctx *sa_ctx,struct sa_head *entries,uint32_t nb_entries,struct socket_ctx *skt_ctx) {return sa_add_rules (sa_ctx, entries, nb_entries,0 , skt_ctx); }static inline int -sa_in_add_rules (struct sa_ctx *sa_ctx,const struct ipsec_sa entries[], +sa_in_add_rules (struct sa_ctx *sa_ctx,struct sa_head *entries,uint32_t nb_entries,struct socket_ctx *skt_ctx) {return sa_add_rules (sa_ctx, entries, nb_entries,1 , skt_ctx);
@@ -1363,7 +1380,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id)if (rc !=0 )rte_exit (EXIT_FAILURE ,"failed to init SAD\n" ); -sa_in_add_rules (ctx->sa_in, sa_in, nb_sa_in, ctx); +sa_in_add_rules (ctx->sa_in, &sa_in_head, nb_sa_in, ctx);if (app_sa_prm.enable !=0 ) { rc = ipsec_satbl_init(ctx->sa_in, nb_sa_in,
@@ -1383,7 +1400,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id)"context %s in socket %d\n" , rte_errno, name, socket_id); -sa_out_add_rules (ctx->sa_out, sa_out, nb_sa_out, ctx); +sa_out_add_rules (ctx->sa_out, &sa_out_head, nb_sa_out, ctx);if (app_sa_prm.enable !=0 ) { rc = ipsec_satbl_init(ctx->sa_out, nb_sa_out,
@@ -1451,21 +1468,22 @@ outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[],/* * Select HW offloads to be used. +* Called before sa_init, so working with mgmt queue */ int sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads, uint64_t *tx_offloads) { + struct ipsec_sa_mgmt *sa_mgmt; struct ipsec_sa *rule; - uint32_t idx_sa; enum rte_security_session_action_type rule_type; *rx_offloads = 0; *tx_offloads = 0; /* Check for inbound rules that use offloads and use this port */ - for (idx_sa = 0; idx_sa < nb_sa_in; idx_sa++) { - rule = &sa_in[idx_sa]; + STAILQ_FOREACH(sa_mgmt, &sa_in_head, next) { + rule = &sa_mgmt->sa; rule_type = ipsec_get_action_type(rule); if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO || rule_type ==
@@ -1475,8 +1493,8 @@ sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads, }/* Check for outbound rules that use offloads and use this port */ - for (idx_sa = 0; idx_sa < nb_sa_out; idx_sa++) { - rule = &sa_out[idx_sa]; + STAILQ_FOREACH(sa_mgmt, &sa_out_head, next) { + rule = &sa_mgmt->sa; rule_type = ipsec_get_action_type(rule); if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO || rule_type ==
Signature · 1 line
2.7.4
v2 cover integrate librte_ipsec SAD into ipsec-secgw
In reply to Vladimir MedvedkinThis series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
v2:
- get rid of maximum sp limitation
Vladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitation
examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 13 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/sa.c | 236 +++++++++++++++++++------------------ examples/ipsec-secgw/sad.c | 90 ++++++++++++++ examples/ipsec-secgw/sad.h | 74 ++++++++++++ examples/ipsec-secgw/sp4.c | 141 ++++++++++++---------- examples/ipsec-secgw/sp6.c | 138 ++++++++++++---------- lib/librte_ipsec/ipsec_sad.c | 20 ++-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 11 files changed, 474 insertions(+), 247 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
Signature · 1 line
2.7.4
PATCH v2 1/5 ipsec: move ipsec sad name length into .h
Move IPSEC_SAD_NAMESIZE into public header
and rename it to RTE_IPSEC_SAD_NAMESIZE
--- lib/librte_ipsec/ipsec_sad.c | 20 ++++++++++---------- lib/librte_ipsec/rte_ipsec_sad.h | 2 ++ 2 files changed, 12 insertions(+), 10 deletions(-)
lib/librte_ipsec/ipsec_sad.c +10 -10
@@ -20,7 +20,6 @@* 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>" */ #define SAD_FORMAT SAD_PREFIX "%s"
@@ -34,7 +33,7 @@ struct hash_cnt { };struct rte_ipsec_sad { -char name[IPSEC_SAD_NAMESIZE ]; +char name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_hash *hash[RTE_IPSEC_SAD_KEY_TYPE_MASK ];/* Array to track number of more specific rules * (spi_dip or spi_dip_sip). Used only in add/delete
@@ -231,7 +230,7 @@ struct rte_ipsec_sad * rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf) { char hash_name[RTE_HASH_NAMESIZE]; -char sad_name[IPSEC_SAD_NAMESIZE ]; +char sad_name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_tailq_entry *te;struct rte_ipsec_sad_list *sad_list;struct rte_ipsec_sad *sad, *tmp_sad =NULL ;
@@ -249,8 +248,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)return NULL ; } - ret =snprintf (sad_name,IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); -if (ret <0 || ret >=IPSEC_SAD_NAMESIZE ) { + ret =snprintf (sad_name,RTE_IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); +if (ret <0 || ret >=RTE_IPSEC_SAD_NAMESIZE ) { rte_errno =ENAMETOOLONG ;return NULL ; }
@@ -326,7 +325,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)/* guarantee there's no existing */ TAILQ_FOREACH(te, sad_list, next) { tmp_sad = (struct rte_ipsec_sad *)te->data; -if (strncmp (sad_name, tmp_sad->name,IPSEC_SAD_NAMESIZE ) ==0 ) +if (strncmp (sad_name, tmp_sad->name, +RTE_IPSEC_SAD_NAMESIZE ) ==0 )break ; }if (te !=NULL ) {
@@ -354,14 +354,14 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)struct rte_ipsec_sad *rte_ipsec_sad_find_existing (const char *name) { -char sad_name[IPSEC_SAD_NAMESIZE ]; +char sad_name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_ipsec_sad *sad =NULL ;struct rte_tailq_entry *te;struct rte_ipsec_sad_list *sad_list;int ret; - ret =snprintf (sad_name,IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); -if (ret <0 || ret >=IPSEC_SAD_NAMESIZE ) { + ret =snprintf (sad_name,RTE_IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); +if (ret <0 || ret >=RTE_IPSEC_SAD_NAMESIZE ) { rte_errno =ENAMETOOLONG ;return NULL ; }
@@ -372,7 +372,7 @@ rte_ipsec_sad_find_existing(const char *name)rte_mcfg_tailq_read_lock (); TAILQ_FOREACH(te, sad_list, next) { sad = (struct rte_ipsec_sad *) te->data; -if (strncmp (sad_name, sad->name,IPSEC_SAD_NAMESIZE ) ==0 ) +if (strncmp (sad_name, sad->name,RTE_IPSEC_SAD_NAMESIZE ) ==0 )break ; }rte_mcfg_tailq_read_unlock ();
lib/librte_ipsec/rte_ipsec_sad.h +2 -0
@@ -47,6 +47,8 @@ union rte_ipsec_sad_key {struct rte_ipsec_sadv6_key v6; }; +/** Max number of characters in SAD name. */ +#define RTE_IPSEC_SAD_NAMESIZE 64/** Flag to create SAD with ipv6 dip and sip addresses */ #define RTE_IPSEC_SAD_FLAG_IPV6 0x1/** Flag to support reader writer concurrency */
Signature · 1 line
2.7.4
PATCH v2 2/5 examples/ipsec-secgw: implement inbound SAD
In reply to Vladimir MedvedkinAdd initial support for librte_ipsec SAD library
--- examples/ipsec-secgw/ipsec.h | 11 ++++++ examples/ipsec-secgw/sad.c | 90 ++++++++++++++++++++++++++++++++++++++++++++ examples/ipsec-secgw/sad.h | 74 ++++++++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
examples/ipsec-secgw/ipsec.h +11 -0
@@ -53,6 +53,17 @@ struct ipsec_xform;struct rte_mbuf ;struct ipsec_sa ; +/* +* Keeps number of configured SA's of each type: +* transport +* v4 tunnel +* v6 tunnel +*/ +struct ipsec_sa_cnt { +uint32_t nb_trn; +uint32_t nb_v4_tun; +uint32_t nb_v6_tun; +};typedef int32_t (*ipsec_xform_fn )(struct rte_mbuf *m,struct ipsec_sa *sa,struct rte_crypto_op *cop);
examples/ipsec-secgw/sad.c new file +90 -0
90 lines not on this page · raw message
examples/ipsec-secgw/sad.h new file +74 -0
74 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v2 3/5 examples/ipsec-secgw: integrate inbound SAD
In reply to Vladimir MedvedkinIntegrate ipsec SAD support into secgw app:
1. Use SAD library for inbound SA lookup
2. Changes in struct sa_ctx:
- sa array allocates dynamically depending on number of configured sa
- All SA's are kept one by one without using SPI2IDX
3. SP's userdata now contain index of SA in sa_ctx instead of SPI
4. Get rid of SPI2IDX macro
--- examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 2 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/sa.c | 160 +++++++++++++++++-------------------- examples/ipsec-secgw/sp4.c | 24 +++--- examples/ipsec-secgw/sp6.c | 24 +++--- 7 files changed, 110 insertions(+), 107 deletions(-)
examples/ipsec-secgw/Makefile +1 -0
@@ -12,6 +12,7 @@ SRCS-y += esp.c SRCS-y += sp4.c SRCS-y += sp6.c SRCS-y += sa.c +SRCS-y += sad.c SRCS-y += rt.c SRCS-y += ipsec_process.c SRCS-y += ipsec-secgw.c
examples/ipsec-secgw/ipsec-secgw.c +2 -2
@@ -601,7 +601,7 @@ inbound_sp_sa(struct sp_ctx *sp, struct sa_ctx *sa, struct traffic_type *ip,continue ; } - sa_idx =SPI2IDX (res); + sa_idx = res -1 ;if (!inbound_sa_check (sa, m, sa_idx)) {rte_pktmbuf_free (m);continue ;
@@ -688,7 +688,7 @@ outbound_sp(struct sp_ctx *sp, struct traffic_type *ip, j =0 ;for (i =0 ; i < ip->num; i++) { m = ip->pkts[i]; - sa_idx =SPI2IDX (ip->res[i]); + sa_idx = ip->res[i] -1 ;if (ip->res[i] ==DISCARD )rte_pktmbuf_free (m);else if (ip->res[i] ==BYPASS )
examples/ipsec-secgw/ipsec.h +1 -1
@@ -363,7 +363,7 @@ sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],* or -ENOENT otherwise. */ int -sa_spi_present (uint32_t spi,int inbound); +sa_spi_present (struct sa_ctx *sa_ctx,uint32_t spi,int inbound);void sa_init (struct socket_ctx *ctx,int32_t socket_id);
examples/ipsec-secgw/meson.build +1 -1
@@ -10,5 +10,5 @@ deps += ['security', 'lpm', 'acl', 'hash', 'ip_frag', 'ipsec'] allow_experimental_apis = true sources = files( 'esp.c', 'ipsec.c', 'ipsec_process.c', 'ipsec-secgw.c', - 'parser.c', 'rt.c', 'sa.c', 'sp4.c', 'sp6.c' + 'parser.c', 'rt.c', 'sa.c', 'sad.c', 'sp4.c', 'sp6.c' )
examples/ipsec-secgw/sa.c +75 -85
311 lines not on this page · raw message
examples/ipsec-secgw/sp4.c +15 -9
@@ -493,10 +493,11 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules,* check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value (int inbound) +check_spi_value (struct sa_ctx *sa_ctx,int inbound) {uint32_t i, num, spi; -const struct acl4_rules *acr; +int32_t spi_idx; +struct acl4_rules *acr;if (inbound !=0 ) { acr = acl4_rules_in;
@@ -508,11 +509,16 @@ check_spi_value(int inbound)for (i =0 ; i != num; i++) { spi = acr[i].data.userdata; -if (spi !=DISCARD && spi !=BYPASS && -sa_spi_present (spi, inbound) <0 ) { -RTE_LOG (ERR ,IPSEC ,"SPI %u is not present in SAD\n" , - spi); -return -ENOENT ; +if (spi !=DISCARD && spi !=BYPASS ) { + spi_idx =sa_spi_present (sa_ctx, spi, inbound); +if (spi_idx <0 ) { +RTE_LOG (ERR ,IPSEC , +"SPI %u is not present in SAD\n" , + spi); +return -ENOENT ; + } +/* Update userdata with spi index */ + acr[i].data.userdata = spi_idx +1 ; } }
@@ -535,11 +541,11 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id)rte_exit (EXIT_FAILURE ,"Outbound SP DB for socket %u already " "initialized\n" , socket_id); -if (check_spi_value (1 ) <0 ) +if (check_spi_value (ctx->sa_in,1 ) <0 )rte_exit (EXIT_FAILURE ,"Inbound IPv4 SP DB has unmatched in SAD SPIs\n" ); -if (check_spi_value (0 ) <0 ) +if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv4 SP DB has unmatched in SAD SPIs\n" );
examples/ipsec-secgw/sp6.c +15 -9
@@ -625,10 +625,11 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_rules *rules,* check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value (int inbound) +check_spi_value (struct sa_ctx *sa_ctx,int inbound) {uint32_t i, num, spi; -const struct acl6_rules *acr; +int32_t spi_idx; +struct acl6_rules *acr;if (inbound !=0 ) { acr = acl6_rules_in;
@@ -640,11 +641,16 @@ check_spi_value(int inbound)for (i =0 ; i != num; i++) { spi = acr[i].data.userdata; -if (spi !=DISCARD && spi !=BYPASS && -sa_spi_present (spi, inbound) <0 ) { -RTE_LOG (ERR ,IPSEC ,"SPI %u is not present in SAD\n" , - spi); -return -ENOENT ; +if (spi !=DISCARD && spi !=BYPASS ) { + spi_idx =sa_spi_present (sa_ctx, spi, inbound); +if (spi_idx <0 ) { +RTE_LOG (ERR ,IPSEC , +"SPI %u is not present in SAD\n" , + spi); +return -ENOENT ; + } +/* Update userdata with spi index */ + acr[i].data.userdata = spi_idx +1 ; } }
@@ -667,11 +673,11 @@ sp6_init(struct socket_ctx *ctx, int32_t socket_id)rte_exit (EXIT_FAILURE ,"Outbound IPv6 SP DB for socket %u " "already initialized\n" , socket_id); -if (check_spi_value (1 ) <0 ) +if (check_spi_value (ctx->sa_in,1 ) <0 )rte_exit (EXIT_FAILURE ,"Inbound IPv6 SP DB has unmatched in SAD SPIs\n" ); -if (check_spi_value (0 ) <0 ) +if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv6 SP DB has unmatched in SAD SPIs\n" );
Signature · 1 line
2.7.4
PATCH v2 4/5 examples/ipsec-secgw: get rid of maximum sa limitation
In reply to Vladimir MedvedkinParse config file and save SA's into linked list
instead of flat array with predefined size.
--- examples/ipsec-secgw/sa.c | 78 +++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 30 deletions(-)
examples/ipsec-secgw/sa.c +48 -30
@@ -20,6 +20,7 @@#include <rte_random.h> #include <rte_ethdev.h> #include <rte_malloc.h> +#include <sys/queue.h> #include "ipsec.h" #include "esp.h"
@@ -133,11 +134,17 @@ const struct supported_aead_algo aead_algos[] = { } }; -static struct ipsec_sa sa_out[IPSEC_SA_MAX_ENTRIES ]; +struct ipsec_sa_mgmt { +STAILQ_ENTRY (ipsec_sa_mgmt) next; +struct ipsec_sa sa; +}; +STAILQ_HEAD (sa_head, ipsec_sa_mgmt); + +static struct sa_head sa_out_head =STAILQ_HEAD_INITIALIZER (sa_out_head);static uint32_t nb_sa_out;static struct ipsec_sa_cnt sa_out_cnt; -static struct ipsec_sa sa_in[IPSEC_SA_MAX_ENTRIES ]; +static struct sa_head sa_in_head =STAILQ_HEAD_INITIALIZER (sa_in_head);static uint32_t nb_sa_in;static struct ipsec_sa_cnt sa_in_cnt;
@@ -228,6 +235,8 @@ void parse_sa_tokens(char **tokens, uint32_t n_tokens, struct parse_status *status) { +struct ipsec_sa_mgmt *sa_mgmt; +struct sa_head *head;struct ipsec_sa *rule =NULL ;struct rte_ipsec_session *ips;uint32_t ti;/*token index*/
@@ -243,27 +252,21 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens,uint32_t portid_p =0 ;uint32_t fallback_p =0 ; + sa_mgmt =calloc (1 ,sizeof (struct ipsec_sa_mgmt )); +if (sa_mgmt ==NULL ) +return ; + + rule = &sa_mgmt->sa; +if (strcmp (tokens[0 ],"in" ) ==0 ) { ri = &nb_sa_in; sa_cnt = &sa_in_cnt; - -APP_CHECK (*ri <=IPSEC_SA_MAX_ENTRIES -1 , status, -"too many sa rules, abort insertion\n" ); -if (status->status <0 ) -return ; - - rule = &sa_in[*ri]; + head = &sa_in_head; rule->direction =RTE_SECURITY_IPSEC_SA_DIR_INGRESS ; }else { ri = &nb_sa_out; sa_cnt = &sa_out_cnt; - -APP_CHECK (*ri <=IPSEC_SA_MAX_ENTRIES -1 , status, -"too many sa rules, abort insertion\n" ); -if (status->status <0 ) -return ; - - rule = &sa_out[*ri]; + head = &sa_out_head; rule->direction =RTE_SECURITY_IPSEC_SA_DIR_EGRESS ; }
@@ -687,6 +690,7 @@ parse_sa_tokens(char **tokens, uint32_t n_tokens, rule->portid =-1 ; } +STAILQ_INSERT_TAIL (head, sa_mgmt, next); *ri = *ri +1 ; }
@@ -956,12 +960,13 @@ sa_add_address_inline_crypto(struct ipsec_sa *sa) }static int -sa_add_rules (struct sa_ctx *sa_ctx,const struct ipsec_sa entries[], +sa_add_rules (struct sa_ctx *sa_ctx,struct sa_head *entries,uint32_t nb_entries,uint32_t inbound,struct socket_ctx *skt_ctx) { +struct ipsec_sa_mgmt *sa_mgmt;struct ipsec_sa *sa; -uint32_t i, idx; +uint32_t idx;uint16_t iv_length, aad_length;int inline_status;int32_t rc;
@@ -970,15 +975,18 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],/* for ESN upper 32 bits of SQN also need to be part of AAD */ aad_length = (app_sa_prm.enable_esn !=0 ) ?sizeof (uint32_t ) :0 ; -for (i =0 ; i < nb_entries; i++) { - idx = i; + sa_mgmt =STAILQ_FIRST (entries); +for (idx =0 ; idx < nb_entries; idx++) { +if (sa_mgmt ==NULL ) +rte_exit (EXIT_FAILURE ,"SA mgmt queue is broken\n" ); + sa = &sa_ctx->sa[idx];if (sa->spi !=0 ) {printf ("Index %u already in use by SPI %u\n" , idx, sa->spi);return -EINVAL ; } - *sa = entries[i]; + *sa = sa_mgmt->sa;if (inbound) { rc =ipsec_sad_add (&sa_ctx->sad, sa);
@@ -1114,20 +1122,29 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[],print_one_sa_rule (sa, inbound); } + sa_mgmt =STAILQ_NEXT (sa_mgmt, next); } +for (sa_mgmt =STAILQ_FIRST (entries); sa_mgmt !=NULL ; + sa_mgmt =STAILQ_FIRST (entries)) { +STAILQ_REMOVE_HEAD (entries, next); +free (sa_mgmt); + } + +STAILQ_INIT (entries); +return 0 ; }static inline int -sa_out_add_rules (struct sa_ctx *sa_ctx,const struct ipsec_sa entries[], +sa_out_add_rules (struct sa_ctx *sa_ctx,struct sa_head *entries,uint32_t nb_entries,struct socket_ctx *skt_ctx) {return sa_add_rules (sa_ctx, entries, nb_entries,0 , skt_ctx); }static inline int -sa_in_add_rules (struct sa_ctx *sa_ctx,const struct ipsec_sa entries[], +sa_in_add_rules (struct sa_ctx *sa_ctx,struct sa_head *entries,uint32_t nb_entries,struct socket_ctx *skt_ctx) {return sa_add_rules (sa_ctx, entries, nb_entries,1 , skt_ctx);
@@ -1363,7 +1380,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id)if (rc !=0 )rte_exit (EXIT_FAILURE ,"failed to init SAD\n" ); -sa_in_add_rules (ctx->sa_in, sa_in, nb_sa_in, ctx); +sa_in_add_rules (ctx->sa_in, &sa_in_head, nb_sa_in, ctx);if (app_sa_prm.enable !=0 ) { rc = ipsec_satbl_init(ctx->sa_in, nb_sa_in,
@@ -1383,7 +1400,7 @@ sa_init(struct socket_ctx *ctx, int32_t socket_id)"context %s in socket %d\n" , rte_errno, name, socket_id); -sa_out_add_rules (ctx->sa_out, sa_out, nb_sa_out, ctx); +sa_out_add_rules (ctx->sa_out, &sa_out_head, nb_sa_out, ctx);if (app_sa_prm.enable !=0 ) { rc = ipsec_satbl_init(ctx->sa_out, nb_sa_out,
@@ -1451,21 +1468,22 @@ outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[],/* * Select HW offloads to be used. +* Called before sa_init, so working with mgmt queue */ int sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads, uint64_t *tx_offloads) { + struct ipsec_sa_mgmt *sa_mgmt; struct ipsec_sa *rule; - uint32_t idx_sa; enum rte_security_session_action_type rule_type; *rx_offloads = 0; *tx_offloads = 0; /* Check for inbound rules that use offloads and use this port */ - for (idx_sa = 0; idx_sa < nb_sa_in; idx_sa++) { - rule = &sa_in[idx_sa]; + STAILQ_FOREACH(sa_mgmt, &sa_in_head, next) { + rule = &sa_mgmt->sa; rule_type = ipsec_get_action_type(rule); if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO || rule_type ==
@@ -1475,8 +1493,8 @@ sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads, }/* Check for outbound rules that use offloads and use this port */ - for (idx_sa = 0; idx_sa < nb_sa_out; idx_sa++) { - rule = &sa_out[idx_sa]; + STAILQ_FOREACH(sa_mgmt, &sa_out_head, next) { + rule = &sa_mgmt->sa; rule_type = ipsec_get_action_type(rule); if ((rule_type == RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO || rule_type ==
Signature · 1 line
2.7.4
PATCH v2 5/5 examples/ipsec-secgw: get rid of maximum sp limitation
In reply to Vladimir MedvedkinParse config file and save SP rules into linked list instead of flat array with predefined size.
--- examples/ipsec-secgw/sp4.c | 121 ++++++++++++++++++++++++++------------------- examples/ipsec-secgw/sp6.c | 118 +++++++++++++++++++++++-------------------- 2 files changed, 134 insertions(+), 105 deletions(-)
examples/ipsec-secgw/sp4.c +69 -52
@@ -8,6 +8,7 @@#include <sys/types.h> #include <netinet/in.h> #include <netinet/ip.h> +#include <sys/queue.h> #include <rte_acl.h> #include <rte_ip.h>
@@ -15,8 +16,6 @@#include "ipsec.h" #include "parser.h" -#define MAX_ACL_RULE_NUM 1024 -#define IPV4_DST_FROM_SP (acr) \ (rte_cpu_to_be_32((acr).field[DST_FIELD_IPV4].value.u32))
@@ -97,16 +96,24 @@ static struct rte_acl_field_def ip4_defs[NUM_FIELDS_IPV4] = {RTE_ACL_RULE_DEF (acl4_rules,RTE_DIM (ip4_defs)); -static struct acl4_rules acl4_rules_out[MAX_ACL_RULE_NUM ]; +struct ipsec_sp_mgmt { +STAILQ_ENTRY (ipsec_sp_mgmt) next; +struct acl4_rules sp; +}; +STAILQ_HEAD (sp_head, ipsec_sp_mgmt); + +static struct sp_head sp_out_head =STAILQ_HEAD_INITIALIZER (sp_out_head);static uint32_t nb_acl4_rules_out; -static struct acl4_rules acl4_rules_in[MAX_ACL_RULE_NUM ]; +static struct sp_head sp_in_head =STAILQ_HEAD_INITIALIZER (sp_in_head);static uint32_t nb_acl4_rules_in;void parse_sp4_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status) { +struct ipsec_sp_mgmt *sp_mgmt; +struct sp_head *head;struct acl4_rules *rule_ipv4 =NULL ;uint32_t *ri =NULL ;/* rule index */
@@ -124,25 +131,18 @@ parse_sp4_tokens(char **tokens, uint32_t n_tokens,uint32_t sport_p =0 ;uint32_t dport_p =0 ; + sp_mgmt =calloc (1 ,sizeof (struct ipsec_sp_mgmt )); +if (sp_mgmt ==NULL ) +return ; + + rule_ipv4 = &sp_mgmt->sp; +if (strcmp (tokens[1 ],"in" ) ==0 ) { ri = &nb_acl4_rules_in; - -APP_CHECK (*ri <=MAX_ACL_RULE_NUM -1 , status, -"too many sp rules, abort insertion\n" ); -if (status->status <0 ) -return ; - - rule_ipv4 = &acl4_rules_in[*ri]; - + head = &sp_in_head; }else if (strcmp (tokens[1 ],"out" ) ==0 ) { ri = &nb_acl4_rules_out; - -APP_CHECK (*ri <=MAX_ACL_RULE_NUM -1 , status, -"too many sp rules, abort insertion\n" ); -if (status->status <0 ) -return ; - - rule_ipv4 = &acl4_rules_out[*ri]; + head = &sp_out_head; }else {APP_CHECK (0 , status,"unrecognized input \"%s\", expect" " \"in\" or \"out\"\n" , tokens[ti]);
@@ -400,6 +400,7 @@ parse_sp4_tokens(char **tokens, uint32_t n_tokens,if (status->status <0 )return ; +STAILQ_INSERT_TAIL (head, sp_mgmt, next); *ri = *ri +1 ; }
@@ -443,18 +444,34 @@ dump_ip4_rules(const struct acl4_rules *rule, int32_t num, int32_t extra) }static struct rte_acl_ctx * -acl4_init (const char *name,int32_t socketid,const struct acl4_rules *rules, +acl4_init (const char *name,int32_t socketid,struct sp_head *rules_list,uint32_t rules_nb) {char s[PATH_MAX ];struct rte_acl_param acl_param;struct rte_acl_config acl_build_param;struct rte_acl_ctx *ctx; +struct acl4_rules *rules;/* Temporary array containing rules */ +struct ipsec_sp_mgmt *sp_mgmt; +uint32_t i; -printf ("Creating SP context with %u max rules\n" ,MAX_ACL_RULE_NUM ); +printf ("Creating SP context with %u rules\n" , rules_nb);memset (&acl_param,0 ,sizeof (acl_param)); +/* Create flat array of rules which is needed for acl context */ + rules =calloc (rules_nb,sizeof (struct acl4_rules )); +if (rules ==NULL ) +rte_exit (EXIT_FAILURE ,"Can't allocate rules array\n" ); + + sp_mgmt =STAILQ_FIRST (rules_list); +for (i =0 ; i < rules_nb; i++) { +if (sp_mgmt ==NULL ) +rte_exit (EXIT_FAILURE ,"SP list is broken\n" ); + rules[i] = sp_mgmt->sp; + sp_mgmt =STAILQ_NEXT (sp_mgmt, next); + } +/* Create ACL contexts */ snprintf (s,sizeof (s),"%s_%d" , name, socketid);
@@ -464,7 +481,7 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules, acl_param.name = s; acl_param.socket_id = socketid; acl_param.rule_size =RTE_ACL_RULE_SZ (RTE_DIM (ip4_defs)); - acl_param.max_rule_num =MAX_ACL_RULE_NUM ; + acl_param.max_rule_num = rules_nb; ctx =rte_acl_create (&acl_param);if (ctx ==NULL )
@@ -486,6 +503,7 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules,rte_acl_dump (ctx); +free (rules);return ctx; }
@@ -495,20 +513,19 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules,static int check_spi_value (struct sa_ctx *sa_ctx,int inbound) { -uint32_t i, num, spi; +uint32_t spi;int32_t spi_idx; -struct acl4_rules *acr; +struct ipsec_sp_mgmt *sp_mgmt; +struct sp_head *head; -if (inbound !=0 ) { - acr = acl4_rules_in; - num = nb_acl4_rules_in; - }else { - acr = acl4_rules_out; - num = nb_acl4_rules_out; - } +if (inbound !=0 ) + head = &sp_in_head; +else + head = &sp_out_head; -for (i =0 ; i != num; i++) { - spi = acr[i].data.userdata; + + STAILQ_FOREACH(sp_mgmt, head, next) { + spi = sp_mgmt->sp.data.userdata;if (spi !=DISCARD && spi !=BYPASS ) { spi_idx =sa_spi_present (sa_ctx, spi, inbound);if (spi_idx <0 ) {
@@ -518,7 +535,7 @@ check_spi_value(struct sa_ctx *sa_ctx, int inbound)return -ENOENT ; }/* Update userdata with spi index */ - acr[i].data.userdata = spi_idx +1 ; + sp_mgmt->sp.data.userdata = spi_idx +1 ; } }
@@ -548,11 +565,10 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id)if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv4 SP DB has unmatched in SAD SPIs\n" ); -if (nb_acl4_rules_in >0 ) { name ="sp_ip4_in" ; ctx->sp_ip4_in = (struct sp_ctx *)acl4_init (name, - socket_id, acl4_rules_in, nb_acl4_rules_in); + socket_id, &sp_in_head, nb_acl4_rules_in); }else RTE_LOG (WARNING ,IPSEC ,"No IPv4 SP Inbound rule " "specified\n" );
@@ -560,7 +576,7 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id)if (nb_acl4_rules_out >0 ) { name ="sp_ip4_out" ; ctx->sp_ip4_out = (struct sp_ctx *)acl4_init (name, - socket_id, acl4_rules_out, nb_acl4_rules_out); + socket_id, &sp_out_head, nb_acl4_rules_out); }else RTE_LOG (WARNING ,IPSEC ,"No IPv4 SP Outbound rule " "specified\n" );
@@ -573,27 +589,28 @@ int sp4_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2], uint32_t mask[2]) { - uint32_t i, num; -const struct acl4_rules *acr; + uint32_t i = 0; +struct ipsec_sp_mgmt *sp_mgmt; +struct sp_head *head; -if (inbound !=0 ) { - acr = acl4_rules_in; - num = nb_acl4_rules_in; - }else { - acr = acl4_rules_out; - num = nb_acl4_rules_out; - } +if (inbound !=0 ) + head = &sp_in_head; +else + head = &sp_out_head; -for (i =0 ; i != num; i++) { -if (acr[i].data.userdata == spi) { + STAILQ_FOREACH(sp_mgmt, head, next) { +if (sp_mgmt->sp.data.userdata == spi) {if (NULL != ip_addr &&NULL != mask) { - ip_addr[0 ].ip.ip4 =IPV4_SRC_FROM_SP (acr[i]); - ip_addr[1 ].ip.ip4 =IPV4_DST_FROM_SP (acr[i]); - mask[0 ] =IPV4_SRC_MASK_FROM_SP (acr[i]); - mask[1 ] =IPV4_DST_MASK_FROM_SP (acr[i]); + ip_addr[0 ].ip.ip4 = +IPV4_SRC_FROM_SP (sp_mgmt->sp); + ip_addr[1 ].ip.ip4 = +IPV4_DST_FROM_SP (sp_mgmt->sp); + mask[0 ] =IPV4_SRC_MASK_FROM_SP (sp_mgmt->sp); + mask[1 ] =IPV4_DST_MASK_FROM_SP (sp_mgmt->sp); }return i; } + i++; }return -ENOENT ;
examples/ipsec-secgw/sp6.c +65 -53
230 lines not on this page · raw message
Signature · 1 line
2.7.4
v3 cover integrate librte_ipsec SAD into ipsec-secgw
In reply to Vladimir MedvedkinThis series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
v3:
- parse SA and SP into sorted array instead of linked list
v2:
- get rid of maximum sp limitation
Vladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitation
examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 15 ++- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 234 +++++++++++++++++++++---------------- examples/ipsec-secgw/sad.c | 94 +++++++++++++++ examples/ipsec-secgw/sad.h | 74 ++++++++++++ examples/ipsec-secgw/sp4.c | 114 +++++++++++++----- examples/ipsec-secgw/sp6.c | 112 +++++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 ++-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 507 insertions(+), 178 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
Signature · 1 line
2.7.4
PATCH v3 1/5 ipsec: move ipsec sad name length into .h
Move IPSEC_SAD_NAMESIZE into public header
and rename it to RTE_IPSEC_SAD_NAMESIZE
--- lib/librte_ipsec/ipsec_sad.c | 20 ++++++++++---------- lib/librte_ipsec/rte_ipsec_sad.h | 2 ++ 2 files changed, 12 insertions(+), 10 deletions(-)
lib/librte_ipsec/ipsec_sad.c +10 -10
@@ -20,7 +20,6 @@* 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>" */ #define SAD_FORMAT SAD_PREFIX "%s"
@@ -34,7 +33,7 @@ struct hash_cnt { };struct rte_ipsec_sad { -char name[IPSEC_SAD_NAMESIZE ]; +char name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_hash *hash[RTE_IPSEC_SAD_KEY_TYPE_MASK ];/* Array to track number of more specific rules * (spi_dip or spi_dip_sip). Used only in add/delete
@@ -231,7 +230,7 @@ struct rte_ipsec_sad * rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf) { char hash_name[RTE_HASH_NAMESIZE]; -char sad_name[IPSEC_SAD_NAMESIZE ]; +char sad_name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_tailq_entry *te;struct rte_ipsec_sad_list *sad_list;struct rte_ipsec_sad *sad, *tmp_sad =NULL ;
@@ -249,8 +248,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)return NULL ; } - ret =snprintf (sad_name,IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); -if (ret <0 || ret >=IPSEC_SAD_NAMESIZE ) { + ret =snprintf (sad_name,RTE_IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); +if (ret <0 || ret >=RTE_IPSEC_SAD_NAMESIZE ) { rte_errno =ENAMETOOLONG ;return NULL ; }
@@ -326,7 +325,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)/* guarantee there's no existing */ TAILQ_FOREACH(te, sad_list, next) { tmp_sad = (struct rte_ipsec_sad *)te->data; -if (strncmp (sad_name, tmp_sad->name,IPSEC_SAD_NAMESIZE ) ==0 ) +if (strncmp (sad_name, tmp_sad->name, +RTE_IPSEC_SAD_NAMESIZE ) ==0 )break ; }if (te !=NULL ) {
@@ -354,14 +354,14 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)struct rte_ipsec_sad *rte_ipsec_sad_find_existing (const char *name) { -char sad_name[IPSEC_SAD_NAMESIZE ]; +char sad_name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_ipsec_sad *sad =NULL ;struct rte_tailq_entry *te;struct rte_ipsec_sad_list *sad_list;int ret; - ret =snprintf (sad_name,IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); -if (ret <0 || ret >=IPSEC_SAD_NAMESIZE ) { + ret =snprintf (sad_name,RTE_IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); +if (ret <0 || ret >=RTE_IPSEC_SAD_NAMESIZE ) { rte_errno =ENAMETOOLONG ;return NULL ; }
@@ -372,7 +372,7 @@ rte_ipsec_sad_find_existing(const char *name)rte_mcfg_tailq_read_lock (); TAILQ_FOREACH(te, sad_list, next) { sad = (struct rte_ipsec_sad *) te->data; -if (strncmp (sad_name, sad->name,IPSEC_SAD_NAMESIZE ) ==0 ) +if (strncmp (sad_name, sad->name,RTE_IPSEC_SAD_NAMESIZE ) ==0 )break ; }rte_mcfg_tailq_read_unlock ();
lib/librte_ipsec/rte_ipsec_sad.h +2 -0
@@ -47,6 +47,8 @@ union rte_ipsec_sad_key {struct rte_ipsec_sadv6_key v6; }; +/** Max number of characters in SAD name. */ +#define RTE_IPSEC_SAD_NAMESIZE 64/** Flag to create SAD with ipv6 dip and sip addresses */ #define RTE_IPSEC_SAD_FLAG_IPV6 0x1/** Flag to support reader writer concurrency */
Signature · 1 line
2.7.4
PATCH v3 2/5 examples/ipsec-secgw: implement inbound SAD
In reply to Vladimir MedvedkinAdd initial support for librte_ipsec SAD library
--- examples/ipsec-secgw/ipsec.h | 11 ++++++ examples/ipsec-secgw/sad.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ examples/ipsec-secgw/sad.h | 74 ++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
examples/ipsec-secgw/ipsec.h +11 -0
@@ -53,6 +53,17 @@ struct ipsec_xform;struct rte_mbuf ;struct ipsec_sa ; +/* +* Keeps number of configured SA's of each type: +* transport +* v4 tunnel +* v6 tunnel +*/ +struct ipsec_sa_cnt { +uint32_t nb_trn; +uint32_t nb_v4_tun; +uint32_t nb_v6_tun; +};typedef int32_t (*ipsec_xform_fn )(struct rte_mbuf *m,struct ipsec_sa *sa,struct rte_crypto_op *cop);
examples/ipsec-secgw/sad.c new file +94 -0
94 lines not on this page · raw message
examples/ipsec-secgw/sad.h new file +74 -0
74 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v3 3/5 examples/ipsec-secgw: integrate inbound SAD
In reply to Vladimir MedvedkinIntegrate ipsec SAD support into secgw app:
1. Use SAD library for inbound SA lookup
2. Changes in struct sa_ctx:
- sa array allocates dynamically depending on number of configured sa
- All SA's are kept one by one without using SPI2IDX
3. SP's userdata now contain index of SA in sa_ctx instead of SPI
4. Get rid of SPI2IDX macro
--- examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 3 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/sa.c | 160 +++++++++++++++++-------------------- examples/ipsec-secgw/sp4.c | 24 +++--- examples/ipsec-secgw/sp6.c | 24 +++--- 7 files changed, 110 insertions(+), 108 deletions(-)
examples/ipsec-secgw/Makefile +1 -0
@@ -12,6 +12,7 @@ SRCS-y += esp.c SRCS-y += sp4.c SRCS-y += sp6.c SRCS-y += sa.c +SRCS-y += sad.c SRCS-y += rt.c SRCS-y += ipsec_process.c SRCS-y += ipsec-secgw.c
examples/ipsec-secgw/ipsec-secgw.c +2 -2
@@ -601,7 +601,7 @@ inbound_sp_sa(struct sp_ctx *sp, struct sa_ctx *sa, struct traffic_type *ip,continue ; } - sa_idx =SPI2IDX (res); + sa_idx = res -1 ;if (!inbound_sa_check (sa, m, sa_idx)) {rte_pktmbuf_free (m);continue ;
@@ -688,7 +688,7 @@ outbound_sp(struct sp_ctx *sp, struct traffic_type *ip, j =0 ;for (i =0 ; i < ip->num; i++) { m = ip->pkts[i]; - sa_idx =SPI2IDX (ip->res[i]); + sa_idx = ip->res[i] -1 ;if (ip->res[i] ==DISCARD )rte_pktmbuf_free (m);else if (ip->res[i] ==BYPASS )
examples/ipsec-secgw/ipsec.h +1 -2
@@ -38,7 +38,6 @@#define DEFAULT_MAX_CATEGORIES 1#define IPSEC_SA_MAX_ENTRIES (128)/* must be power of 2, max 2 power 30 */ -#define SPI2IDX (spi) (spi & (IPSEC_SA_MAX_ENTRIES - 1))#define INVALID_SPI (0)#define DISCARD INVALID_SPI
@@ -363,7 +362,7 @@ sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],* or -ENOENT otherwise. */ int -sa_spi_present (uint32_t spi,int inbound); +sa_spi_present (struct sa_ctx *sa_ctx,uint32_t spi,int inbound);void sa_init (struct socket_ctx *ctx,int32_t socket_id);
examples/ipsec-secgw/meson.build +1 -1
@@ -10,5 +10,5 @@ deps += ['security', 'lpm', 'acl', 'hash', 'ip_frag', 'ipsec'] allow_experimental_apis = true sources = files( 'esp.c', 'ipsec.c', 'ipsec_process.c', 'ipsec-secgw.c', - 'parser.c', 'rt.c', 'sa.c', 'sp4.c', 'sp6.c' + 'parser.c', 'rt.c', 'sa.c', 'sad.c', 'sp4.c', 'sp6.c' )
examples/ipsec-secgw/sa.c +75 -85
311 lines not on this page · raw message
examples/ipsec-secgw/sp4.c +15 -9
@@ -493,10 +493,11 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules,* check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value (int inbound) +check_spi_value (struct sa_ctx *sa_ctx,int inbound) {uint32_t i, num, spi; -const struct acl4_rules *acr; +int32_t spi_idx; +struct acl4_rules *acr;if (inbound !=0 ) { acr = acl4_rules_in;
@@ -508,11 +509,16 @@ check_spi_value(int inbound)for (i =0 ; i != num; i++) { spi = acr[i].data.userdata; -if (spi !=DISCARD && spi !=BYPASS && -sa_spi_present (spi, inbound) <0 ) { -RTE_LOG (ERR ,IPSEC ,"SPI %u is not present in SAD\n" , - spi); -return -ENOENT ; +if (spi !=DISCARD && spi !=BYPASS ) { + spi_idx =sa_spi_present (sa_ctx, spi, inbound); +if (spi_idx <0 ) { +RTE_LOG (ERR ,IPSEC , +"SPI %u is not present in SAD\n" , + spi); +return -ENOENT ; + } +/* Update userdata with spi index */ + acr[i].data.userdata = spi_idx +1 ; } }
@@ -535,11 +541,11 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id)rte_exit (EXIT_FAILURE ,"Outbound SP DB for socket %u already " "initialized\n" , socket_id); -if (check_spi_value (1 ) <0 ) +if (check_spi_value (ctx->sa_in,1 ) <0 )rte_exit (EXIT_FAILURE ,"Inbound IPv4 SP DB has unmatched in SAD SPIs\n" ); -if (check_spi_value (0 ) <0 ) +if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv4 SP DB has unmatched in SAD SPIs\n" );
examples/ipsec-secgw/sp6.c +15 -9
@@ -625,10 +625,11 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_rules *rules,* check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value (int inbound) +check_spi_value (struct sa_ctx *sa_ctx,int inbound) {uint32_t i, num, spi; -const struct acl6_rules *acr; +int32_t spi_idx; +struct acl6_rules *acr;if (inbound !=0 ) { acr = acl6_rules_in;
@@ -640,11 +641,16 @@ check_spi_value(int inbound)for (i =0 ; i != num; i++) { spi = acr[i].data.userdata; -if (spi !=DISCARD && spi !=BYPASS && -sa_spi_present (spi, inbound) <0 ) { -RTE_LOG (ERR ,IPSEC ,"SPI %u is not present in SAD\n" , - spi); -return -ENOENT ; +if (spi !=DISCARD && spi !=BYPASS ) { + spi_idx =sa_spi_present (sa_ctx, spi, inbound); +if (spi_idx <0 ) { +RTE_LOG (ERR ,IPSEC , +"SPI %u is not present in SAD\n" , + spi); +return -ENOENT ; + } +/* Update userdata with spi index */ + acr[i].data.userdata = spi_idx +1 ; } }
@@ -667,11 +673,11 @@ sp6_init(struct socket_ctx *ctx, int32_t socket_id)rte_exit (EXIT_FAILURE ,"Outbound IPv6 SP DB for socket %u " "already initialized\n" , socket_id); -if (check_spi_value (1 ) <0 ) +if (check_spi_value (ctx->sa_in,1 ) <0 )rte_exit (EXIT_FAILURE ,"Inbound IPv6 SP DB has unmatched in SAD SPIs\n" ); -if (check_spi_value (0 ) <0 ) +if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv6 SP DB has unmatched in SAD SPIs\n" );
Signature · 1 line
2.7.4
PATCH v3 4/5 examples/ipsec-secgw: get rid of maximum sa limitation
In reply to Vladimir MedvedkinGet rid of maximum SA limitation.
Keep parsed SA's into the sorted by SPI value array. Use binary search in the sorted SA array to find appropriate SA for a given SPI.
--- examples/ipsec-secgw/ipsec.h | 1 - examples/ipsec-secgw/parser.c | 2 ++ examples/ipsec-secgw/parser.h | 3 ++ examples/ipsec-secgw/sa.c | 74 +++++++++++++++++++++++++++++++++---------- 4 files changed, 62 insertions(+), 18 deletions(-)
examples/ipsec-secgw/ipsec.h +0 -1
@@ -37,7 +37,6 @@#define DEFAULT_MAX_CATEGORIES 1 -#define IPSEC_SA_MAX_ENTRIES (128)/* must be power of 2, max 2 power 30 */ #define INVALID_SPI (0)#define DISCARD INVALID_SPI
examples/ipsec-secgw/parser.c +2 -0
@@ -642,6 +642,8 @@ parse_cfg_file(const char *cfg_filename)cmdline_stdin_exit (cl);fclose (f); +sa_sort_arr (); +return 0 ; error_exit:
examples/ipsec-secgw/parser.h +3 -0
@@ -75,6 +75,9 @@ parse_sp6_tokens(char **tokens, uint32_t n_tokens, struct parse_status *status);void +sa_sort_arr (void ); + +void parse_sa_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status);
examples/ipsec-secgw/sa.c +57 -17
123 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v3 5/5 examples/ipsec-secgw: get rid of maximum sp limitation
In reply to Vladimir MedvedkinGet rid of maximum SP limitation.
Keep parsed SP's into the sorted by SPI value array. Use binary search in the sorted SP array to find appropriate SP for a given SPI.
--- examples/ipsec-secgw/parser.c | 2 + examples/ipsec-secgw/parser.h | 6 +++ examples/ipsec-secgw/sp4.c | 90 +++++++++++++++++++++++++++++++++---------- examples/ipsec-secgw/sp6.c | 88 ++++++++++++++++++++++++++++++++---------- 4 files changed, 144 insertions(+), 42 deletions(-)
examples/ipsec-secgw/parser.c +2 -0
@@ -643,6 +643,8 @@ parse_cfg_file(const char *cfg_filename)fclose (f);sa_sort_arr (); +sp4_sort_arr (); +sp6_sort_arr ();return 0 ;
examples/ipsec-secgw/parser.h +6 -0
@@ -67,10 +67,16 @@ int parse_range(const char *token, uint16_t *low, uint16_t *high);void +sp4_sort_arr (void ); + +void parse_sp4_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status);void +sp6_sort_arr (void ); + +void parse_sp6_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status);
examples/ipsec-secgw/sp4.c +69 -21
150 lines not on this page · raw message
examples/ipsec-secgw/sp6.c +67 -21
148 lines not on this page · raw message
Signature · 1 line
2.7.4
v4 cover integrate librte_ipsec SAD into ipsec-secgw
In reply to Vladimir MedvedkinThis series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
v4:
- put tunnel SA's into SAD with SPI_ONLY type for performance reason
v3:
- parse SA and SP into sorted array instead of linked list
v2:
- get rid of maximum sp limitation
Vladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitation
examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 11 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 256 +++++++++++++++++++++++-------------- examples/ipsec-secgw/sad.c | 90 +++++++++++++ examples/ipsec-secgw/sad.h | 74 +++++++++++ examples/ipsec-secgw/sp4.c | 114 ++++++++++++----- examples/ipsec-secgw/sp6.c | 112 +++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 +-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 528 insertions(+), 171 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
Signature · 1 line
2.7.4
PATCH v4 1/5 ipsec: move ipsec sad name length into .h
Move IPSEC_SAD_NAMESIZE into public header
and rename it to RTE_IPSEC_SAD_NAMESIZE
--- lib/librte_ipsec/ipsec_sad.c | 20 ++++++++++---------- lib/librte_ipsec/rte_ipsec_sad.h | 2 ++ 2 files changed, 12 insertions(+), 10 deletions(-)
lib/librte_ipsec/ipsec_sad.c +10 -10
@@ -20,7 +20,6 @@* 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>" */ #define SAD_FORMAT SAD_PREFIX "%s"
@@ -34,7 +33,7 @@ struct hash_cnt { };struct rte_ipsec_sad { -char name[IPSEC_SAD_NAMESIZE ]; +char name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_hash *hash[RTE_IPSEC_SAD_KEY_TYPE_MASK ];/* Array to track number of more specific rules * (spi_dip or spi_dip_sip). Used only in add/delete
@@ -231,7 +230,7 @@ struct rte_ipsec_sad * rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf) { char hash_name[RTE_HASH_NAMESIZE]; -char sad_name[IPSEC_SAD_NAMESIZE ]; +char sad_name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_tailq_entry *te;struct rte_ipsec_sad_list *sad_list;struct rte_ipsec_sad *sad, *tmp_sad =NULL ;
@@ -249,8 +248,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)return NULL ; } - ret =snprintf (sad_name,IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); -if (ret <0 || ret >=IPSEC_SAD_NAMESIZE ) { + ret =snprintf (sad_name,RTE_IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); +if (ret <0 || ret >=RTE_IPSEC_SAD_NAMESIZE ) { rte_errno =ENAMETOOLONG ;return NULL ; }
@@ -326,7 +325,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)/* guarantee there's no existing */ TAILQ_FOREACH(te, sad_list, next) { tmp_sad = (struct rte_ipsec_sad *)te->data; -if (strncmp (sad_name, tmp_sad->name,IPSEC_SAD_NAMESIZE ) ==0 ) +if (strncmp (sad_name, tmp_sad->name, +RTE_IPSEC_SAD_NAMESIZE ) ==0 )break ; }if (te !=NULL ) {
@@ -354,14 +354,14 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)struct rte_ipsec_sad *rte_ipsec_sad_find_existing (const char *name) { -char sad_name[IPSEC_SAD_NAMESIZE ]; +char sad_name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_ipsec_sad *sad =NULL ;struct rte_tailq_entry *te;struct rte_ipsec_sad_list *sad_list;int ret; - ret =snprintf (sad_name,IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); -if (ret <0 || ret >=IPSEC_SAD_NAMESIZE ) { + ret =snprintf (sad_name,RTE_IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); +if (ret <0 || ret >=RTE_IPSEC_SAD_NAMESIZE ) { rte_errno =ENAMETOOLONG ;return NULL ; }
@@ -372,7 +372,7 @@ rte_ipsec_sad_find_existing(const char *name)rte_mcfg_tailq_read_lock (); TAILQ_FOREACH(te, sad_list, next) { sad = (struct rte_ipsec_sad *) te->data; -if (strncmp (sad_name, sad->name,IPSEC_SAD_NAMESIZE ) ==0 ) +if (strncmp (sad_name, sad->name,RTE_IPSEC_SAD_NAMESIZE ) ==0 )break ; }rte_mcfg_tailq_read_unlock ();
lib/librte_ipsec/rte_ipsec_sad.h +2 -0
@@ -47,6 +47,8 @@ union rte_ipsec_sad_key {struct rte_ipsec_sadv6_key v6; }; +/** Max number of characters in SAD name. */ +#define RTE_IPSEC_SAD_NAMESIZE 64/** Flag to create SAD with ipv6 dip and sip addresses */ #define RTE_IPSEC_SAD_FLAG_IPV6 0x1/** Flag to support reader writer concurrency */
Signature · 1 line
2.7.4
Re: [dpdk-dev] [PATCH v4 1/5] ipsec: move ipsec sad name length into .h
Quoted 9 lines
-----Original Message-----
From: Medvedkin, Vladimir <[email protected]>
Sent: Tuesday, January 14, 2020 2:27 PM
To: [email protected]
Cc: Ananyev, Konstantin <[email protected]>; [email protected]
Subject: [PATCH v4 1/5] ipsec: move ipsec sad name length into .h
Quoted 5 lines
Move
IPSEC_SAD_NAMESIZEinto public header
and rename it toRTE_IPSEC_SAD_NAMESIZESigned-off-by Vladimir Medvedkin <[email protected]>---
Quoted 2 lines
--
2.7.4
PATCH v4 2/5 examples/ipsec-secgw: implement inbound SAD
In reply to Vladimir MedvedkinAdd initial support for librte_ipsec SAD library
--- examples/ipsec-secgw/ipsec.h | 7 ++++ examples/ipsec-secgw/sad.c | 90 ++++++++++++++++++++++++++++++++++++++++++++ examples/ipsec-secgw/sad.h | 74 ++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
examples/ipsec-secgw/ipsec.h +7 -0
@@ -53,6 +53,13 @@ struct ipsec_xform;struct rte_mbuf ;struct ipsec_sa ; +/* +* Keeps number of configured SA's for each address family: +*/ +struct ipsec_sa_cnt { +uint32_t nb_v4; +uint32_t nb_v6; +};typedef int32_t (*ipsec_xform_fn )(struct rte_mbuf *m,struct ipsec_sa *sa,struct rte_crypto_op *cop);
examples/ipsec-secgw/sad.c new file +90 -0
90 lines not on this page · raw message
examples/ipsec-secgw/sad.h new file +74 -0
74 lines not on this page · raw message
Signature · 1 line
2.7.4
Re: [dpdk-dev] [PATCH v4 2/5] examples/ipsec-secgw: implement inbound SAD
Quoted 7 lines
Add initial support for
librte_ipsecSAD librarySigned-off-by Vladimir Medvedkin <[email protected]>---
Quoted 1 line
2.7.4
PATCH v4 3/5 examples/ipsec-secgw: integrate inbound SAD
In reply to Vladimir MedvedkinIntegrate ipsec SAD support into secgw app:
1. Use SAD library for inbound SA lookup
2. Changes in struct sa_ctx:
- sa array allocates dynamically depending on number of configured sa
- All SA's are kept one by one without using SPI2IDX
3. SP's userdata now contain index of SA in sa_ctx instead of SPI
4. Get rid of SPI2IDX macro
--- examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 3 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/sa.c | 182 +++++++++++++++++++++---------------- examples/ipsec-secgw/sp4.c | 24 +++-- examples/ipsec-secgw/sp6.c | 24 +++-- 7 files changed, 139 insertions(+), 101 deletions(-)
examples/ipsec-secgw/Makefile +1 -0
@@ -12,6 +12,7 @@ SRCS-y += esp.c SRCS-y += sp4.c SRCS-y += sp6.c SRCS-y += sa.c +SRCS-y += sad.c SRCS-y += rt.c SRCS-y += ipsec_process.c SRCS-y += ipsec-secgw.c
examples/ipsec-secgw/ipsec-secgw.c +2 -2
@@ -601,7 +601,7 @@ inbound_sp_sa(struct sp_ctx *sp, struct sa_ctx *sa, struct traffic_type *ip,continue ; } - sa_idx =SPI2IDX (res); + sa_idx = res -1 ;if (!inbound_sa_check (sa, m, sa_idx)) {rte_pktmbuf_free (m);continue ;
@@ -688,7 +688,7 @@ outbound_sp(struct sp_ctx *sp, struct traffic_type *ip, j =0 ;for (i =0 ; i < ip->num; i++) { m = ip->pkts[i]; - sa_idx =SPI2IDX (ip->res[i]); + sa_idx = ip->res[i] -1 ;if (ip->res[i] ==DISCARD )rte_pktmbuf_free (m);else if (ip->res[i] ==BYPASS )
examples/ipsec-secgw/ipsec.h +1 -2
@@ -38,7 +38,6 @@#define DEFAULT_MAX_CATEGORIES 1#define IPSEC_SA_MAX_ENTRIES (128)/* must be power of 2, max 2 power 30 */ -#define SPI2IDX (spi) (spi & (IPSEC_SA_MAX_ENTRIES - 1))#define INVALID_SPI (0)#define DISCARD INVALID_SPI
@@ -359,7 +358,7 @@ sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],* or -ENOENT otherwise. */ int -sa_spi_present (uint32_t spi,int inbound); +sa_spi_present (struct sa_ctx *sa_ctx,uint32_t spi,int inbound);void sa_init (struct socket_ctx *ctx,int32_t socket_id);
examples/ipsec-secgw/meson.build +1 -1
@@ -10,5 +10,5 @@ deps += ['security', 'lpm', 'acl', 'hash', 'ip_frag', 'ipsec'] allow_experimental_apis = true sources = files( 'esp.c', 'ipsec.c', 'ipsec_process.c', 'ipsec-secgw.c', - 'parser.c', 'rt.c', 'sa.c', 'sp4.c', 'sp6.c' + 'parser.c', 'rt.c', 'sa.c', 'sad.c', 'sp4.c', 'sp6.c' )
examples/ipsec-secgw/sa.c +104 -78
343 lines not on this page · raw message
examples/ipsec-secgw/sp4.c +15 -9
@@ -493,10 +493,11 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules,* check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value (int inbound) +check_spi_value (struct sa_ctx *sa_ctx,int inbound) {uint32_t i, num, spi; -const struct acl4_rules *acr; +int32_t spi_idx; +struct acl4_rules *acr;if (inbound !=0 ) { acr = acl4_rules_in;
@@ -508,11 +509,16 @@ check_spi_value(int inbound)for (i =0 ; i != num; i++) { spi = acr[i].data.userdata; -if (spi !=DISCARD && spi !=BYPASS && -sa_spi_present (spi, inbound) <0 ) { -RTE_LOG (ERR ,IPSEC ,"SPI %u is not present in SAD\n" , - spi); -return -ENOENT ; +if (spi !=DISCARD && spi !=BYPASS ) { + spi_idx =sa_spi_present (sa_ctx, spi, inbound); +if (spi_idx <0 ) { +RTE_LOG (ERR ,IPSEC , +"SPI %u is not present in SAD\n" , + spi); +return -ENOENT ; + } +/* Update userdata with spi index */ + acr[i].data.userdata = spi_idx +1 ; } }
@@ -535,11 +541,11 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id)rte_exit (EXIT_FAILURE ,"Outbound SP DB for socket %u already " "initialized\n" , socket_id); -if (check_spi_value (1 ) <0 ) +if (check_spi_value (ctx->sa_in,1 ) <0 )rte_exit (EXIT_FAILURE ,"Inbound IPv4 SP DB has unmatched in SAD SPIs\n" ); -if (check_spi_value (0 ) <0 ) +if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv4 SP DB has unmatched in SAD SPIs\n" );
examples/ipsec-secgw/sp6.c +15 -9
@@ -625,10 +625,11 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_rules *rules,* check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value (int inbound) +check_spi_value (struct sa_ctx *sa_ctx,int inbound) {uint32_t i, num, spi; -const struct acl6_rules *acr; +int32_t spi_idx; +struct acl6_rules *acr;if (inbound !=0 ) { acr = acl6_rules_in;
@@ -640,11 +641,16 @@ check_spi_value(int inbound)for (i =0 ; i != num; i++) { spi = acr[i].data.userdata; -if (spi !=DISCARD && spi !=BYPASS && -sa_spi_present (spi, inbound) <0 ) { -RTE_LOG (ERR ,IPSEC ,"SPI %u is not present in SAD\n" , - spi); -return -ENOENT ; +if (spi !=DISCARD && spi !=BYPASS ) { + spi_idx =sa_spi_present (sa_ctx, spi, inbound); +if (spi_idx <0 ) { +RTE_LOG (ERR ,IPSEC , +"SPI %u is not present in SAD\n" , + spi); +return -ENOENT ; + } +/* Update userdata with spi index */ + acr[i].data.userdata = spi_idx +1 ; } }
@@ -667,11 +673,11 @@ sp6_init(struct socket_ctx *ctx, int32_t socket_id)rte_exit (EXIT_FAILURE ,"Outbound IPv6 SP DB for socket %u " "already initialized\n" , socket_id); -if (check_spi_value (1 ) <0 ) +if (check_spi_value (ctx->sa_in,1 ) <0 )rte_exit (EXIT_FAILURE ,"Inbound IPv6 SP DB has unmatched in SAD SPIs\n" ); -if (check_spi_value (0 ) <0 ) +if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv6 SP DB has unmatched in SAD SPIs\n" );
Signature · 1 line
2.7.4
Re: [dpdk-dev] [PATCH v4 3/5] examples/ipsec-secgw: integrate inbound SAD
Quoted 18 lines
-----Original Message-----
From: Medvedkin, Vladimir <[email protected]>
Sent: Tuesday, January 14, 2020 2:27 PM
To: [email protected]
Cc: Ananyev, Konstantin <[email protected]>; [email protected]
Subject: [PATCH v4 3/5] examples/ipsec-secgw: integrate inbound SADIntegrate ipsec SAD support into secgw app:
1. Use SAD library for inbound SA lookup
2. Changes in structsa_ctx:
- sa array allocates dynamically depending on number of configured sa
- All SA's are kept one by one without using SPI2IDX
3. SP's userdata now contain index of SA insa_ctxinstead of SPI
4. Get rid of SPI2IDX macro
Quoted 2 lines
Signed-off-by Vladimir Medvedkin <[email protected]>---
Quoted 1 line
2.7.4
PATCH v4 4/5 examples/ipsec-secgw: get rid of maximum sa limitation
In reply to Vladimir MedvedkinGet rid of maximum SA limitation.
Keep parsed SA's into the sorted by SPI value array. Use binary search in the sorted SA array to find appropriate SA for a given SPI.
--- examples/ipsec-secgw/ipsec.h | 1 - examples/ipsec-secgw/parser.c | 2 ++ examples/ipsec-secgw/parser.h | 3 ++ examples/ipsec-secgw/sa.c | 74 +++++++++++++++++++++++++++++++++---------- 4 files changed, 62 insertions(+), 18 deletions(-)
examples/ipsec-secgw/ipsec.h +0 -1
@@ -37,7 +37,6 @@#define DEFAULT_MAX_CATEGORIES 1 -#define IPSEC_SA_MAX_ENTRIES (128)/* must be power of 2, max 2 power 30 */ #define INVALID_SPI (0)#define DISCARD INVALID_SPI
examples/ipsec-secgw/parser.c +2 -0
@@ -642,6 +642,8 @@ parse_cfg_file(const char *cfg_filename)cmdline_stdin_exit (cl);fclose (f); +sa_sort_arr (); +return 0 ; error_exit:
examples/ipsec-secgw/parser.h +3 -0
@@ -75,6 +75,9 @@ parse_sp6_tokens(char **tokens, uint32_t n_tokens, struct parse_status *status);void +sa_sort_arr (void ); + +void parse_sa_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status);
examples/ipsec-secgw/sa.c +57 -17
123 lines not on this page · raw message
Signature · 1 line
2.7.4
Re: [dpdk-dev] [PATCH v4 4/5] examples/ipsec-secgw: get rid of maximum sa limitation
Quoted 9 lines
-----Original Message-----
From: Medvedkin, Vladimir <[email protected]>
Sent: Tuesday, January 14, 2020 2:27 PM
To: [email protected]
Cc: Ananyev, Konstantin <[email protected]>; [email protected]
Subject: [PATCH v4 4/5] examples/ipsec-secgw: get rid of maximum sa limitation
Quoted 7 lines
Get rid of maximum SA limitation.
Keep parsed SA's into the sorted by SPI value array. Use binary search in the sorted SA array to find appropriate SA for a given SPI.Signed-off-by Vladimir Medvedkin <[email protected]>---
Quoted 1 line
2.7.4
PATCH v4 5/5 examples/ipsec-secgw: get rid of maximum sp limitation
In reply to Vladimir MedvedkinGet rid of maximum SP limitation.
Keep parsed SP's into the sorted by SPI value array. Use binary search in the sorted SP array to find appropriate SP for a given SPI.
--- examples/ipsec-secgw/parser.c | 2 + examples/ipsec-secgw/parser.h | 6 +++ examples/ipsec-secgw/sp4.c | 90 +++++++++++++++++++++++++++++++++---------- examples/ipsec-secgw/sp6.c | 88 ++++++++++++++++++++++++++++++++---------- 4 files changed, 144 insertions(+), 42 deletions(-)
examples/ipsec-secgw/parser.c +2 -0
@@ -643,6 +643,8 @@ parse_cfg_file(const char *cfg_filename)fclose (f);sa_sort_arr (); +sp4_sort_arr (); +sp6_sort_arr ();return 0 ;
examples/ipsec-secgw/parser.h +6 -0
@@ -67,10 +67,16 @@ int parse_range(const char *token, uint16_t *low, uint16_t *high);void +sp4_sort_arr (void ); + +void parse_sp4_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status);void +sp6_sort_arr (void ); + +void parse_sp6_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status);
examples/ipsec-secgw/sp4.c +69 -21
150 lines not on this page · raw message
examples/ipsec-secgw/sp6.c +67 -21
148 lines not on this page · raw message
Signature · 1 line
2.7.4
Re: [dpdk-dev] [PATCH v4 5/5] examples/ipsec-secgw: get rid of maximum sp limitation
Quoted 8 lines
Get rid of maximum SP limitation.
Keep parsed SP's into the sorted by SPI value array. Use binary search in the sorted SP array to find appropriate SP for a given SPI.Signed-off-by Vladimir Medvedkin <[email protected]>---
Quoted 1 line
2.7.4
Hi Vladimir,
There is more than 10% drop with this patchset on NXP hardware with both legacy mode and the ipsec lib mode. This would need some debugging. Didn't you see any drop on intel?
Regards,
Akhil
Quoted 47 lines
-----Original Message-----
From: Vladimir Medvedkin <[email protected]>
Sent: Tuesday, January 14, 2020 7:57 PM
To: [email protected]
Cc: [email protected]; Akhil Goyal <[email protected]>
Subject: [PATCH v4 0/5] integratelibrte_ipsecSAD into ipsec-secgwThis series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
v4:
- put tunnel SA's into SAD withSPI_ONLYtype for performance reasonv3:
- parse SA and SP into sorted array instead of linked listv2:
- get rid of maximum sp limitationVladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitationexamples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 11 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 256 +++++++++++++++++++++++-------------- examples/ipsec-secgw/sad.c | 90 +++++++++++++ examples/ipsec-secgw/sad.h | 74 +++++++++++ examples/ipsec-secgw/sp4.c | 114 ++++++++++++----- examples/ipsec-secgw/sp6.c | 112 +++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 +-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 528 insertions(+), 171 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h--
2.7.4
Hi Vladimir,
The lookup logic for SAD has been brought more closer to real use case, but it looks very high on CPU and should be optimized. We cannot have 10-15% drop because of this change in SA lookup for small packet(82B) sizes where CPU is bottleneck. For large packet sizes it will not impact.
Quoted 52 lines
Hi Vladimir,
There is more than 10% drop with this patchset on NXP hardware with both legacy mode and the ipsec lib mode. This would need some debugging. Didn't you see any drop on intel?
Regards,
AkhilQuoted 22 lines
This series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
v4:
- put tunnel SA's into SAD withSPI_ONLYtype for performance reasonv3:
- parse SA and SP into sorted array instead of linked listv2:
- get rid of maximum sp limitationVladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitationQuoted 7 lines
examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 11 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 256 +++++++++++++++++++++++--------------
Quoted 12 lines
examples/ipsec-secgw/sad.c | 90 +++++++++++++ examples/ipsec-secgw/sad.h | 74 +++++++++++ examples/ipsec-secgw/sp4.c | 114 ++++++++++++----- examples/ipsec-secgw/sp6.c | 112 +++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 +-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 528 insertions(+), 171 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h--
2.7.4
Hi Akhil,
Indeed with our tests we also seeing ~15% perf drop for small packets (~90B) and ~3-4% drop for 1KB packets. While I am looking on a ways to minimize the drop, I think it would be hard, if possible at all to eliminate it completely. Reason for that: current SAD implementation is completely synthetic (using plain array structure indexed by SPI value). That provides a very low overhead, but doesn't provide expected functionality and can't be used in proper implementation. To measure plain IPsec performance without SAD user can still use '--signle-sa' option.
Quoted 55 lines · Akhil Goyal
Hi Vladimir,
There is more than 10% drop with this patchset on NXP hardware with both legacy mode and the ipsec lib mode. This would need some debugging. Didn't you see any drop on intel?
Regards,
AkhilQuoted 47 lines
-----Original Message-----
From: Vladimir Medvedkin <[email protected]>
Sent: Tuesday, January 14, 2020 7:57 PM
To: [email protected]
Cc: [email protected]; Akhil Goyal <[email protected]>
Subject: [PATCH v4 0/5] integratelibrte_ipsecSAD into ipsec-secgwThis series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
v4:
- put tunnel SA's into SAD withSPI_ONLYtype for performance reasonv3:
- parse SA and SP into sorted array instead of linked listv2:
- get rid of maximum sp limitationVladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitationexamples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 11 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 256 +++++++++++++++++++++++-------------- examples/ipsec-secgw/sad.c | 90 +++++++++++++ examples/ipsec-secgw/sad.h | 74 +++++++++++ examples/ipsec-secgw/sp4.c | 114 ++++++++++++----- examples/ipsec-secgw/sp6.c | 112 +++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 +-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 528 insertions(+), 171 deletions(-)create mode 100644
examples/ipsec-secgw/sad.c
create mode 100644examples/ipsec-secgw/sad.h--
2.7.4
Signature · 2 lines
Regards, Vladimir
Hi Vladimir,
The SA lookup logic and management is purely requirement based for the application. The application may only cater to <128 SAs which can be handled based on the current logic. –single-sa option cannot handle this. Sample applications in DPDK are there to showcase the best a hardware can deliver. IMO, we cannot allow this logic on NXP hardwares. We give performance numbers based on IPSec app to customers and we cannot allow 15% degradation. Other vendors(Marvell, ARM, AMD) please comment?
Regards,
Akhil
From: Medvedkin, Vladimir <[email protected]>
Sent: Friday, January 17, 2020 10:35 PM
To: Akhil Goyal <[email protected]>; [email protected]
Cc: [email protected]
Subject: Re: [PATCH v4 0/5] integrate librte_ipsec SAD into ipsec-secgw
Hi Akhil,
Indeed with our tests we also seeing ~15% perf drop for small packets (~90B) and ~3-4% drop for 1KB packets. While I am looking on a ways to minimize the drop, I think it would be hard, if possible at all to eliminate it completely. Reason for that: current SAD implementation is completely synthetic (using plain array structure indexed by SPI value). That provides a very low overhead, but doesn't provide expected functionality and can't be used in proper implementation. To measure plain IPsec performance without SAD user can still use '--signle-sa' option.
On 15/01/2020 15:45, Akhil Goyal wrote:
Hi Vladimir,
There is more than 10% drop with this patchset on NXP hardware with both legacy mode and the ipsec lib mode. This would need some debugging.
Didn't you see any drop on intel?
Regards,
Akhil
-----Original Message-----
From: Vladimir Medvedkin <[email protected]><mailto:[email protected]>
Sent: Tuesday, January 14, 2020 7:57 PM
To: [email protected]<mailto:[email protected]>
Subject: [PATCH v4 0/5] integrate librte_ipsec SAD into ipsec-secgw
This series integrates SA database (SAD) capabilities from ipsec library.
The goal is to make ipsec-secgw RFC compliant regarding inbound SAD.
Also patch series removes hardcoded limitation for maximum number of SA's
and SP's.
v4:
- put tunnel SA's into SAD with SPI_ONLY type for performance reason
v3:
- parse SA and SP into sorted array instead of linked list
v2:
- get rid of maximum sp limitation
Vladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h
examples/ipsec-secgw: implement inbound SAD
examples/ipsec-secgw: integrate inbound SAD
examples/ipsec-secgw: get rid of maximum sa limitation
examples/ipsec-secgw: get rid of maximum sp limitation
examples/ipsec-secgw/Makefile | 1 +
examples/ipsec-secgw/ipsec-secgw.c | 4 +-
examples/ipsec-secgw/ipsec.h | 11 +-
examples/ipsec-secgw/meson.build | 2 +-
examples/ipsec-secgw/parser.c | 4 +
examples/ipsec-secgw/parser.h | 9 ++
examples/ipsec-secgw/sa.c | 256 +++++++++++++++++++++++--------------
examples/ipsec-secgw/sad.c | 90 +++++++++++++
examples/ipsec-secgw/sad.h | 74 +++++++++++
examples/ipsec-secgw/sp4.c | 114 ++++++++++++-----
examples/ipsec-secgw/sp6.c | 112 +++++++++++-----
lib/librte_ipsec/ipsec_sad.c | 20 +--
lib/librte_ipsec/rte_ipsec_sad.h | 2 +
13 files changed, 528 insertions(+), 171 deletions(-)
create mode 100644 examples/ipsec-secgw/sad.c
create mode 100644 examples/ipsec-secgw/sad.h
--
2.7.4
--
Regards,
Vladimir
-->
Hi Vladimir, Akhil,
Marvell is also observing 10-15% drop with the SAD change. I agree with Akhil's opinion and we are not in favor of making this change.
Thanks,
Anoob
From: Akhil Goyal <[email protected]>
Sent: Monday, January 20, 2020 12:14 PM
To: Medvedkin, Vladimir <[email protected]>; [email protected]
Cc: [email protected]; Anoob Joseph <[email protected]>; Thomas Monjalon <[email protected]>; Ravi Kumar <[email protected]>; Ruifeng Wang <[email protected]>
Subject: [EXT] RE: [PATCH v4 0/5] integrate librte_ipsec SAD into ipsec-secgw
External Email
________________________________________
Hi Vladimir,
The SA lookup logic and management is purely requirement based for the application. The application may only cater to <128 SAs which can be handled based on the current logic. –single-sa option cannot handle this. Sample applications in DPDK are there to showcase the best a hardware can deliver. IMO, we cannot allow this logic on NXP hardwares. We give performance numbers based on IPSec app to customers and we cannot allow 15% degradation. Other vendors(Marvell, ARM, AMD) please comment?
Regards,
Akhil
From: Medvedkin, Vladimir <mailto:[email protected]>
Sent: Friday, January 17, 2020 10:35 PM
To: Akhil Goyal <mailto:[email protected]>; mailto:[email protected]
Cc: mailto:[email protected]
Subject: Re: [PATCH v4 0/5] integrate librte_ipsec SAD into ipsec-secgw
Hi Akhil,
Indeed with our tests we also seeing ~15% perf drop for small packets (~90B) and ~3-4% drop for 1KB packets. While I am looking on a ways to minimize the drop, I think it would be hard, if possible at all to eliminate it completely. Reason for that: current SAD implementation is completely synthetic (using plain array structure indexed by SPI value). That provides a very low overhead, but doesn't provide expected functionality and can't be used in proper implementation. To measure plain IPsec performance without SAD user can still use '--signle-sa' option.
On 15/01/2020 15:45, Akhil Goyal wrote:
Hi Vladimir,
There is more than 10% drop with this patchset on NXP hardware with both legacy mode and the ipsec lib mode. This would need some debugging. Didn't you see any drop on intel?
Regards,
Akhil
-----Original Message-----
From: Vladimir Medvedkin mailto:[email protected]
Sent: Tuesday, January 14, 2020 7:57 PM
To: mailto:[email protected]
Cc: mailto:[email protected]; Akhil Goyal mailto:[email protected]
Subject: [PATCH v4 0/5] integrate librte_ipsec SAD into ipsec-secgw
This series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
v4:
- put tunnel SA's into SAD with SPI_ONLY type for performance reason
v3:
- parse SA and SP into sorted array instead of linked list
v2:
- get rid of maximum sp limitation
Vladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitation
examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 11 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 256 +++++++++++++++++++++++-------------- examples/ipsec-secgw/sad.c | 90 +++++++++++++ examples/ipsec-secgw/sad.h | 74 +++++++++++ examples/ipsec-secgw/sp4.c | 114 ++++++++++++----- examples/ipsec-secgw/sp6.c | 112 +++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 +-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 528 insertions(+), 171 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
--
2.7.4
Signature · 3 lines
Regards, Vladimir -->
A message that is not in the archive (sent off-list or not yet received): SN6PR11MB25581C7C8F969AA18EE8C1949A320@SN6PR11MB2558.namprd11.prod.outlook.com
A message that is not in the archive (sent off-list or not yet received): SN6PR11MB25588E3DD326CFC90DD1E3989A320@SN6PR11MB2558.namprd11.prod.outlook.com
v4 cover integrate librte_ipsec SAD into ipsec-secgw
Hi Akhil,
Quoted 4 lines
Hi Vladimir,
The SA lookup logic and management is purely requirement based for the application. The application may only cater to <128 SAs which can
be handled based on the current logic.
Not always, current implementation can handle < 128 SA, whose SPI%128 never match (let say it cant't handle SPI=1 and SPI=129). Yes, what we have right now has nearly zero overhead,
and might be ok for some really simple show-cases.
But for majority of production IPsec implementations,
I believe that definitely wouldn't be enough.
Quoted 2 lines
–single-sa option cannot handle this.
Sample applications in DPDK are there to showcase the best a hardware can deliver.
My thought was - that's the reason we have single-sa option - demonstrate best possible HW perf without minimal SW intervention. For something more serious than that, we use generic SAD implementation.
Quoted 2 lines
IMO, we cannot allow this logic on NXP hardwares. We
give performance numbers based on IPSec app to customers and we cannot allow 15% degradation.
As Vladimir said, we are looking how to improve current SAD numbers
and minimize the drop.
But with same equals - plain array will always be faster than hash table,
so not sure we will be able to match existing performance.
So two questions:
1. What exact case you use for perf testing
(total number of SAs, packets per burst belong to the same/different SAs)?
Might be there is a way to speedup it.
Again if 10-15% is not an affordable drop, which one is: zero or ...?
2. I think there are 2 different directions for ipsec-secgw:
From one-side there is a desire to use it as a show-case for best-possible HW IPsec performance
(which is understandable).
From other side - attempt to make it as close as real-world generic ipsec processing app as possible (support for ESN, replay window, fragmented packets, generic proper SAD, etc). Obviously these goals contradict and it makes really hard for the same app to fulfill both. Any thoughts how to deal with that?
One obvious would be to split the app, anything else?
Konstantin
Quoted 77 lines
Other
vendors(Marvell, ARM, AMD)please comment?
Regards,
Akhil
From: Medvedkin, Vladimir <mailto:[email protected]>
Sent: Friday, January 17, 2020 10:35 PM
To: Akhil Goyal <mailto:[email protected]>; mailto:[email protected]
Cc: mailto:[email protected]
Subject: Re: [PATCH v4 0/5] integratelibrte_ipsecSAD into ipsec-secgwHi Akhil,
Indeed with our tests we also seeing ~15% perf drop for small packets (~90B) and ~3-4% drop for 1KB packets. While I am looking on a ways to minimize the drop, I think it would be hard, if possible at all to eliminate it completely.
Reason for that: current SAD implementation is completely synthetic (using plain array structure indexed by SPI value). That provides a very low overhead, but doesn't provide expected functionality and can't be used in proper implementation.
To measure plain IPsec performance without SAD user can still use '--signle-sa' option.
On 15/01/2020 15:45, Akhil Goyal wrote:
Hi Vladimir,There is more than 10% drop with this patchset on NXP hardware with both legacy mode and the ipsec lib mode. This would need some debugging.
Didn't you see any drop on intel?Regards,
Akhil-----Original Message-----
From: Vladimir Medvedkin mailto:[email protected]
Sent: Tuesday, January 14, 2020 7:57 PM
To: mailto:[email protected]
Cc: mailto:[email protected]; Akhil Goyal mailto:[email protected]
Subject: [PATCH v4 0/5] integratelibrte_ipsecSAD into ipsec-secgwThis series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
v4:
- put tunnel SA's into SAD withSPI_ONLYtype for performance reasonv3:
- parse SA and SP into sorted array instead of linked listv2:
- get rid of maximum sp limitationVladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitationexamples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 11 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 256 +++++++++++++++++++++++-------------- examples/ipsec-secgw/sad.c | 90 +++++++++++++ examples/ipsec-secgw/sad.h | 74 +++++++++++ examples/ipsec-secgw/sp4.c | 114 ++++++++++++----- examples/ipsec-secgw/sp6.c | 112 +++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 +-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 528 insertions(+), 171 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h--
2.7.4--
Regards,
Vladimir
-->
Hi Konstantin,
Quoted 28 lines
Hi Akhil,
Quoted 2 lines
Hi Vladimir,
The SA lookup logic and management is purely requirement based for theapplication.
Quoted 2 lines
The application may only cater to <128 SAs which can be handled based on the current logic.
Not always, current implementation can handle < 128 SA, whose SPI%128 never match (let say it cant't handle SPI=1 and SPI=129). Yes, what we have right now has nearly zero overhead,
and might be ok for some really simple show-cases.
But for majority of production IPsec implementations,
I believe that definitely wouldn't be enough.Quoted 2 lines
–single-sa option cannot handle this.
Sample applications in DPDK are there to showcase the best a hardware candeliver.
My thought was - that's the reason we have single-sa option - demonstrate best possible HW perf without minimal SW intervention. For something more serious than that, we use generic SAD implementation.
Quoted 2 lines
IMO, we cannot allow this logic on NXP hardwares. We
give performance numbers based on IPSec app to customers and we cannotallow 15% degradation.
Quoted 9 lines
As Vladimir said, we are looking how to improve current SAD numbers and minimize the drop.
But with same equals - plain array will always be faster than hash table, so not sure we will be able to match existing performance.
So two questions:
1. What exact case you use for perf testing
(total number of SAs, packets per burst belong to the same/different SAs)? Might be there is a way to speedup it.
Again if 10-15% is not an affordable drop, which one is: zero or ...?
We should add features judiciously, we cannot drop the performance of a benchmarking Application in lieu of adding functionality. We should only add features which are not Impacting the performance significantly.
Every vendor may have different cases. We cannot tune for everybody. However, I see drop in 64 outbound 64 inbound SAs all with different SPI and IPs. Packets per burst = 32 all with different SAs.
Quoted 4 lines
2. I think there are 2 different directions for ipsec-secgw:
From one-side there is a desire to use it as a show-case for best-possible HW
IPsec performance
(which is understandable).
Quoted 8 lines
From other side - attempt to make it as close as real-world generic ipsec
processing app as possible
(support for ESN, replay window, fragmented packets, generic proper SAD,
etc).
Obviously these goals contradict and it makes really hard for the same app to
fulfill both.
Any thoughts how to deal with that?
One obvious would be to split the app, anything else?
We can have a fallback mechanism back to original functionality for whatever feature which has some perf drop.
Splitting an app can be thought of but that would be similar to a full fledged IPSec stack like VPP-IPSec.
Quoted 88 lines
Konstantin
Quoted 11 lines
Other
vendors(Marvell, ARM, AMD)please comment?
Regards,
Akhil
From: Medvedkin, Vladimir <mailto:[email protected]>
Sent: Friday, January 17, 2020 10:35 PM
To: Akhil Goyal <mailto:[email protected]>; mailto:[email protected]
Cc: mailto:[email protected]
Subject: Re: [PATCH v4 0/5] integratelibrte_ipsecSAD into ipsec-secgwHi Akhil,
Indeed with our tests we also seeing ~15% perf drop for small packets (~90B)and ~3-4% drop for 1KB packets. While I am looking on a ways
Quoted 1 line
to minimize the drop, I think it would be hard, if possible at all to eliminate it
completely.
Quoted 1 line
Reason for that: current SAD implementation is completely synthetic (using
plain array structure indexed by SPI value). That provides a very
Quoted 1 line
low overhead, but doesn't provide expected functionality and can't be used in
proper implementation.
Quoted 1 line
To measure plain IPsec performance without SAD user can still use '--signle-sa'
option.
Quoted 4 lines · Akhil Goyal
Hi Vladimir,
There is more than 10% drop with this patchset on NXP hardware with both
legacy mode and the ipsec lib mode. This would need some
Quoted 11 lines
debugging.
Didn't you see any drop on intel?Regards,
Akhil-----Original Message-----
From: Vladimir Medvedkin mailto:[email protected]
Sent: Tuesday, January 14, 2020 7:57 PM
To: mailto:[email protected]
Cc: mailto:[email protected]; Akhil Goyalmailto:[email protected]
Quoted 23 lines
Subject: [PATCH v4 0/5] integrate
librte_ipsecSAD into ipsec-secgwThis series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
v4:
- put tunnel SA's into SAD withSPI_ONLYtype for performance reasonv3:
- parse SA and SP into sorted array instead of linked listv2:
- get rid of maximum sp limitationVladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitationQuoted 7 lines
examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 11 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 256 +++++++++++++++++++++++--------------
Quoted 17 lines
examples/ipsec-secgw/sad.c | 90 +++++++++++++ examples/ipsec-secgw/sad.h | 74 +++++++++++ examples/ipsec-secgw/sp4.c | 114 ++++++++++++----- examples/ipsec-secgw/sp6.c | 112 +++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 +-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 528 insertions(+), 171 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h--
2.7.4--
Regards,
Vladimir
-->
Hi All,
Quoted 40 lines
Hi Konstantin,
Quoted 28 lines
Hi Akhil,
Quoted 2 lines
Hi Vladimir,
The SA lookup logic and management is purely requirement based for theapplication.
Quoted 2 lines
The application may only cater to <128 SAs which can be handled based on the current logic.
Not always, current implementation can handle < 128 SA, whose SPI%128 never match (let say it cant't handle SPI=1 and SPI=129). Yes, what we have right now has nearly zero overhead,
and might be ok for some really simple show-cases.
But for majority of production IPsec implementations,
I believe that definitely wouldn't be enough.Quoted 2 lines
–single-sa option cannot handle this.
Sample applications in DPDK are there to showcase the best a hardware candeliver.
My thought was - that's the reason we have single-sa option - demonstrate best possible HW perf without minimal SW intervention. For something more serious than that, we use generic SAD implementation.
Quoted 2 lines
IMO, we cannot allow this logic on NXP hardwares. We
give performance numbers based on IPSec app to customers and we cannotallow 15% degradation.
Quoted 9 lines
As Vladimir said, we are looking how to improve current SAD numbers and minimize the drop.
But with same equals - plain array will always be faster than hash table, so not sure we will be able to match existing performance.
So two questions:
1. What exact case you use for perf testing
(total number of SAs, packets per burst belong to the same/different SAs)? Might be there is a way to speedup it.
Again if 10-15% is not an affordable drop, which one is: zero or ...?
Quoted 9 lines
We should add features judiciously, we cannot drop the performance of a benchmarking
Application in lieu of adding functionality. We should only add features which are not
Impacting the performance significantly.
Every vendor may have different cases. We cannot tune for everybody. However, I see drop in 64 outbound 64 inbound SAs all with different SPI and IPs. Packets per burst = 32 all with different SAs.
We can have two modes of lookup similar to l3fwd - EM and LPM.
LPM is O(1) while EM is more realistic. Similar logic can be added here as well. With L3fwd also we showcase performance for best case(lpm) and the worst case(em) What Say?
As discussed in the DPDK-status meeting today, this patchset need to be discussed in Techboard meeting. Please include this topic in the upcoming meeting on 29th Jan.
-Akhil
Quoted 111 lines
Quoted 4 lines
2. I think there are 2 different directions for ipsec-secgw:
From one-side there is a desire to use it as a show-case for best-possible HW
IPsec performance
(which is understandable).Quoted 8 lines
From other side - attempt to make it as close as real-world generic ipsec
processing app as possible
(support for ESN, replay window, fragmented packets, generic proper SAD,
etc).
Obviously these goals contradict and it makes really hard for the same app to
fulfill both.
Any thoughts how to deal with that?
One obvious would be to split the app, anything else?We can have a fallback mechanism back to original functionality for whatever feature
which has some perf drop.
Splitting an app can be thought of but that would be similar to a full fledged IPSec stack
like VPP-IPSec.Quoted 12 lines
Konstantin
Quoted 9 lines
Other
vendors(Marvell, ARM, AMD)please comment?
Regards,
Akhil
From: Medvedkin, Vladimir <mailto:[email protected]>
Sent: Friday, January 17, 2020 10:35 PM
To: Akhil Goyal <mailto:[email protected]>; mailto:[email protected]
Cc: mailto:[email protected]
Subject: Re: [PATCH v4 0/5] integratelibrte_ipsecSAD into ipsec-secgwQuoted 8 lines
Quoted 2 lines
Hi Akhil,
Indeed with our tests we also seeing ~15% perf drop for small packets (~90B)and ~3-4% drop for 1KB packets. While I am looking on a ways
Quoted 1 line
to minimize the drop, I think it would be hard, if possible at all to eliminate it
completely.
Quoted 1 line
Reason for that: current SAD implementation is completely synthetic (using
plain array structure indexed by SPI value). That provides a very
Quoted 1 line
low overhead, but doesn't provide expected functionality and can't be used
in
Quoted 2 lines
proper implementation.
Quoted 1 line
To measure plain IPsec performance without SAD user can still use '--signle-
sa'
Quoted 12 lines
option.
Quoted 4 lines · Akhil Goyal
Hi Vladimir,
There is more than 10% drop with this patchset on NXP hardware with both
legacy mode and the ipsec lib mode. This would need some
Quoted 6 lines
debugging.
Didn't you see any drop on intel?Regards,
AkhilQuoted 36 lines
Quoted 5 lines
-----Original Message-----
From: Vladimir Medvedkin mailto:[email protected]
Sent: Tuesday, January 14, 2020 7:57 PM
To: mailto:[email protected]
Cc: mailto:[email protected]; Akhil Goyalmailto:[email protected]
Quoted 30 lines
Subject: [PATCH v4 0/5] integrate
librte_ipsecSAD into ipsec-secgwThis series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
v4:
- put tunnel SA's into SAD withSPI_ONLYtype for performance reasonv3:
- parse SA and SP into sorted array instead of linked listv2:
- get rid of maximum sp limitationVladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitationexamples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 11 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 256 +++++++++++++++++++++++-------------
Quoted 18 lines
-
Quoted 17 lines
examples/ipsec-secgw/sad.c | 90 +++++++++++++ examples/ipsec-secgw/sad.h | 74 +++++++++++ examples/ipsec-secgw/sp4.c | 114 ++++++++++++----- examples/ipsec-secgw/sp6.c | 112 +++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 +-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 528 insertions(+), 171 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h--
2.7.4--
Regards,
Vladimir
-->
Hi Akhil,
Quoted 45 lines
Quoted 35 lines
Quoted 25 lines
Quoted 2 lines
Hi Vladimir,
The SA lookup logic and management is purely requirement based for theapplication.
Quoted 2 lines
The application may only cater to <128 SAs which can be handled based on the current logic.
Not always, current implementation can handle < 128 SA, whose SPI%128 never match (let say it cant't handle SPI=1 and SPI=129). Yes, what we have right now has nearly zero overhead,
and might be ok for some really simple show-cases.
But for majority of production IPsec implementations,
I believe that definitely wouldn't be enough.Quoted 2 lines
–single-sa option cannot handle this.
Sample applications in DPDK are there to showcase the best a hardware candeliver.
My thought was - that's the reason we have single-sa option - demonstrate best possible HW perf without minimal SW intervention. For something more serious than that, we use generic SAD implementation.
Quoted 2 lines
IMO, we cannot allow this logic on NXP hardwares. We
give performance numbers based on IPSec app to customers and we cannotallow 15% degradation.
Quoted 9 lines
As Vladimir said, we are looking how to improve current SAD numbers and minimize the drop.
But with same equals - plain array will always be faster than hash table, so not sure we will be able to match existing performance.
So two questions:
1. What exact case you use for perf testing
(total number of SAs, packets per burst belong to the same/different SAs)? Might be there is a way to speedup it.
Again if 10-15% is not an affordable drop, which one is: zero or ...?Quoted 9 lines
We should add features judiciously, we cannot drop the performance of a benchmarking
Application in lieu of adding functionality. We should only add features which are not
Impacting the performance significantly.
Every vendor may have different cases. We cannot tune for everybody. However, I see drop in 64 outbound 64 inbound SAs all with different SPI and IPs. Packets per burst = 32 all with different SAs.
Quoted 4 lines
We can have two modes of lookup similar to l3fwd - EM and LPM.
LPM is O(1) while EM is more realistic. Similar logic can be added here as well. With L3fwd also we showcase performance for best case(lpm) and the worst case(em) What Say?
We discussed it off-line with Vladimir and came up with similar idea:
Have a proper/generic SAD implementation and add limited size plain-array on top of it as 1xway associative cache.
So for the case when all active SAs fit into the cache and no SPI collisions, we should have same performance as now (with plain array).
From other side, we'll still have generic/scalable/rfc compliant implementation. Sort of best sides from two words.
Plans are to submit v4 with such approach in next few days.
Quoted 3 lines
As discussed in the DPDK-status meeting today, this patchset need to be discussed in Techboard meeting. Please include this topic in the upcoming meeting on 29th Jan.
As I said above, I think we found a way to deal with it without any perf drop for existing cases.
Though sure, if you feel some extra discussion is needed, let's request to put it into agenda.
Konstantin
Quoted 114 lines
-Akhil
Quoted 111 lines
Quoted 4 lines
2. I think there are 2 different directions for ipsec-secgw:
From one-side there is a desire to use it as a show-case for best-possible HW
IPsec performance
(which is understandable).Quoted 8 lines
From other side - attempt to make it as close as real-world generic ipsec
processing app as possible
(support for ESN, replay window, fragmented packets, generic proper SAD,
etc).
Obviously these goals contradict and it makes really hard for the same app to
fulfill both.
Any thoughts how to deal with that?
One obvious would be to split the app, anything else?We can have a fallback mechanism back to original functionality for whatever feature
which has some perf drop.
Splitting an app can be thought of but that would be similar to a full fledged IPSec stack
like VPP-IPSec.Quoted 12 lines
Konstantin
Quoted 9 lines
Other
vendors(Marvell, ARM, AMD)please comment?
Regards,
Akhil
From: Medvedkin, Vladimir <mailto:[email protected]>
Sent: Friday, January 17, 2020 10:35 PM
To: Akhil Goyal <mailto:[email protected]>; mailto:[email protected]
Cc: mailto:[email protected]
Subject: Re: [PATCH v4 0/5] integratelibrte_ipsecSAD into ipsec-secgwQuoted 8 lines
Quoted 2 lines
Hi Akhil,
Indeed with our tests we also seeing ~15% perf drop for small packets (~90B)and ~3-4% drop for 1KB packets. While I am looking on a ways
Quoted 1 line
to minimize the drop, I think it would be hard, if possible at all to eliminate it
completely.
Quoted 1 line
Reason for that: current SAD implementation is completely synthetic (using
plain array structure indexed by SPI value). That provides a very
Quoted 1 line
low overhead, but doesn't provide expected functionality and can't be used
in
Quoted 2 lines
proper implementation.
Quoted 1 line
To measure plain IPsec performance without SAD user can still use '--signle-
sa'
Quoted 12 lines
option.
Quoted 4 lines · Akhil Goyal
Hi Vladimir,
There is more than 10% drop with this patchset on NXP hardware with both
legacy mode and the ipsec lib mode. This would need some
Quoted 6 lines
debugging.
Didn't you see any drop on intel?Regards,
AkhilQuoted 36 lines
Quoted 5 lines
-----Original Message-----
From: Vladimir Medvedkin mailto:[email protected]
Sent: Tuesday, January 14, 2020 7:57 PM
To: mailto:[email protected]
Cc: mailto:[email protected]; Akhil Goyalmailto:[email protected]
Quoted 30 lines
Subject: [PATCH v4 0/5] integrate
librte_ipsecSAD into ipsec-secgwThis series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
v4:
- put tunnel SA's into SAD withSPI_ONLYtype for performance reasonv3:
- parse SA and SP into sorted array instead of linked listv2:
- get rid of maximum sp limitationVladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitationexamples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 11 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 256 +++++++++++++++++++++++-------------
Quoted 18 lines
-
Quoted 17 lines
examples/ipsec-secgw/sad.c | 90 +++++++++++++ examples/ipsec-secgw/sad.h | 74 +++++++++++ examples/ipsec-secgw/sp4.c | 114 ++++++++++++----- examples/ipsec-secgw/sp6.c | 112 +++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 +-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 528 insertions(+), 171 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h--
2.7.4--
Regards,
Vladimir
-->
Hi Konstantin,
Quoted 57 lines
Hi Akhil,
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 2 lines
Hi Vladimir,
The SA lookup logic and management is purely requirement based for theapplication.
Quoted 2 lines
The application may only cater to <128 SAs which can be handled based on the current logic.
Not always, current implementation can handle < 128 SA, whose SPI%128 never match (let say it cant't handle SPI=1 and SPI=129). Yes, what we have right now has nearly zero overhead,
and might be ok for some really simple show-cases.
But for majority of production IPsec implementations,
I believe that definitely wouldn't be enough.Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
–single-sa option cannot handle this.
Sample applications in DPDK are there to showcase the best a hardwarecan
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
deliver.
My thought was - that's the reason we have single-sa option - demonstrate best possible HW perf without minimal SW intervention. For something more serious than that, we use generic SAD implementation.
Quoted 2 lines
IMO, we cannot allow this logic on NXP hardwares. We give performance numbers based on IPSec app to customers and we
cannot
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
allow 15% degradation.
As Vladimir said, we are looking how to improve current SAD numbers and minimize the drop.
But with same equals - plain array will always be faster than hash table, so not sure we will be able to match existing performance.
So two questions:
1. What exact case you use for perf testing
(total number of SAs, packets per burst belong to the same/different SAs)? Might be there is a way to speedup it.
Again if 10-15% is not an affordable drop, which one is: zero or ...?Quoted 7 lines
Quoted 7 lines
We should add features judiciously, we cannot drop the performance of a benchmarking
Application in lieu of adding functionality. We should only add features which are not
Impacting the performance significantly.
Every vendor may have different cases. We cannot tune for everybody. However, I see drop in 64 outbound 64 inbound SAs all with different SPI andIPs.
Quoted 6 lines
Quoted 2 lines
Packets per burst = 32 all with different SAs.
We can have two modes of lookup similar to l3fwd - EM and LPM.
LPM is O(1) while EM is more realistic. Similar logic can be added here as well. With L3fwd also we showcase performance for best case(lpm) and the worstcase(em)
Quoted 1 line
What Say?
Quoted 8 lines
We discussed it off-line with Vladimir and came up with similar idea:
Have a proper/generic SAD implementation and add limited size plain-array on top of it as 1xway associative cache.
So for the case when all active SAs fit into the cache and no SPI collisions, we should have same performance as now (with plain array).
From other side, we'll still have generic/scalable/rfc compliant implementation. Sort of best sides from two words.
Plans are to submit v4 with such approach in next few days.
OK lets check the v4 before moving the discussion to techboard. @Thomas: Do you have more thoughts on this? Should we get it added in the agenda Or wait for the v4?
Quoted 140 lines
Quoted 3 lines
As discussed in the DPDK-status meeting today, this patchset need to be
discussed in
Quoted 1 line
Techboard meeting. Please include this topic in the upcoming meeting on 29th
Jan.
As I said above, I think we found a way to deal with it without any perf drop for existing cases.
Though sure, if you feel some extra discussion is needed, let's request to put it into agenda.Konstantin
Quoted 5 lines
-Akhil
Quoted 2 lines
Quoted 2 lines
2. I think there are 2 different directions for ipsec-secgw:
From one-side there is a desire to use it as a show-case for best-possibleHW
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
IPsec performance
(which is understandable).
From other side - attempt to make it as close as real-world generic ipsec
processing app as possible
(support for ESN, replay window, fragmented packets, generic properSAD,
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
etc).
Obviously these goals contradict and it makes really hard for the sameapp to
Quoted 5 lines
Quoted 5 lines
Quoted 3 lines
fulfill both.
Any thoughts how to deal with that?
One obvious would be to split the app, anything else?We can have a fallback mechanism back to original functionality for
whatever
Quoted 18 lines
Quoted 18 lines
feature
which has some perf drop.
Splitting an app can be thought of but that would be similar to a full fledged IPSec stack
like VPP-IPSec.Quoted 12 lines
Konstantin
Quoted 9 lines
Other
vendors(Marvell, ARM, AMD)please comment?
Regards,
Akhil
From: Medvedkin, Vladimir <mailto:[email protected]>
Sent: Friday, January 17, 2020 10:35 PM
To: Akhil Goyal <mailto:[email protected]>; mailto:[email protected]
Cc: mailto:[email protected]
Subject: Re: [PATCH v4 0/5] integratelibrte_ipsecSAD into ipsec-secgwQuoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Hi Akhil,
Indeed with our tests we also seeing ~15% perf drop for small packets(~90B)
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
and ~3-4% drop for 1KB packets. While I am looking on a ways
Quoted 1 line
to minimize the drop, I think it would be hard, if possible at all to
eliminate it
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
completely.
Quoted 1 line
Reason for that: current SAD implementation is completely synthetic
(using
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
plain array structure indexed by SPI value). That provides a very
Quoted 1 line
low overhead, but doesn't provide expected functionality and can't be
used
Quoted 3 lines
Quoted 3 lines
in
Quoted 2 lines
proper implementation.
Quoted 1 line
To measure plain IPsec performance without SAD user can still use '--
signle-
Quoted 6 lines
Quoted 6 lines
sa'
Quoted 5 lines
option.
Quoted 4 lines · Akhil Goyal
Hi Vladimir,
There is more than 10% drop with this patchset on NXP hardware with
both
Quoted 12 lines
Quoted 12 lines
Quoted 12 lines
legacy mode and the ipsec lib mode. This would need some
Quoted 11 lines
debugging.
Didn't you see any drop on intel?Regards,
Akhil-----Original Message-----
From: Vladimir Medvedkin mailto:[email protected]
Sent: Tuesday, January 14, 2020 7:57 PM
To: mailto:[email protected]
Cc: mailto:[email protected]; Akhil GoyalQuoted 6 lines
Quoted 6 lines
Quoted 6 lines
mailto:[email protected]
Quoted 5 lines
Subject: [PATCH v4 0/5] integrate
librte_ipsecSAD into ipsec-secgwThis series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of
SA's
Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
and SP's.
v4:
- put tunnel SA's into SAD withSPI_ONLYtype for performance reasonv3:
- parse SA and SP into sorted array instead of linked listv2:
- get rid of maximum sp limitationVladimir Medvedkin (5):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitationQuoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 11 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 256 +++++++++++++++++++++++-----------
Quoted 19 lines
Quoted 19 lines
--
Quoted 18 lines
-
Quoted 17 lines
examples/ipsec-secgw/sad.c | 90 +++++++++++++ examples/ipsec-secgw/sad.h | 74 +++++++++++ examples/ipsec-secgw/sp4.c | 114 ++++++++++++----- examples/ipsec-secgw/sp6.c | 112 +++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 +-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 528 insertions(+), 171 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h--
2.7.4--
Regards,
Vladimir
-->
23/01/2020 13:56, Akhil Goyal:
Quoted 67 lines
Hi Konstantin,
Quoted 57 lines
Hi Akhil,
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 2 lines
Hi Vladimir,
The SA lookup logic and management is purely requirement based for theapplication.
Quoted 2 lines
The application may only cater to <128 SAs which can be handled based on the current logic.
Not always, current implementation can handle < 128 SA, whose SPI%128 never match (let say it cant't handle SPI=1 and SPI=129). Yes, what we have right now has nearly zero overhead,
and might be ok for some really simple show-cases.
But for majority of production IPsec implementations,
I believe that definitely wouldn't be enough.Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
–single-sa option cannot handle this.
Sample applications in DPDK are there to showcase the best a hardwarecan
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
deliver.
My thought was - that's the reason we have single-sa option - demonstrate best possible HW perf without minimal SW intervention. For something more serious than that, we use generic SAD implementation.
Quoted 2 lines
IMO, we cannot allow this logic on NXP hardwares. We give performance numbers based on IPSec app to customers and we
cannot
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
allow 15% degradation.
As Vladimir said, we are looking how to improve current SAD numbers and minimize the drop.
But with same equals - plain array will always be faster than hash table, so not sure we will be able to match existing performance.
So two questions:
1. What exact case you use for perf testing
(total number of SAs, packets per burst belong to the same/different SAs)? Might be there is a way to speedup it.
Again if 10-15% is not an affordable drop, which one is: zero or ...?Quoted 7 lines
Quoted 7 lines
We should add features judiciously, we cannot drop the performance of a benchmarking
Application in lieu of adding functionality. We should only add features which are not
Impacting the performance significantly.
Every vendor may have different cases. We cannot tune for everybody. However, I see drop in 64 outbound 64 inbound SAs all with different SPI andIPs.
Quoted 6 lines
Quoted 2 lines
Packets per burst = 32 all with different SAs.
We can have two modes of lookup similar to l3fwd - EM and LPM.
LPM is O(1) while EM is more realistic. Similar logic can be added here as well. With L3fwd also we showcase performance for best case(lpm) and the worstcase(em)
Quoted 1 line
What Say?
Quoted 8 lines
We discussed it off-line with Vladimir and came up with similar idea:
Have a proper/generic SAD implementation and add limited size plain-array on top of it as 1xway associative cache.
So for the case when all active SAs fit into the cache and no SPI collisions, we should have same performance as now (with plain array).
From other side, we'll still have generic/scalable/rfc compliant implementation. Sort of best sides from two words.
Plans are to submit v4 with such approach in next few days.
Quoted 3 lines
OK lets check the v4 before moving the discussion to techboard. @Thomas: Do you have more thoughts on this? Should we get it added in the agenda Or wait for the v4?
If v4 is good for both cases, it lowers the priority of the discussion.
But still, it would be interesting to state the objectives of the examples:
- show API usage?
- show feature performance?
- show best hardware performance?
- what else?
Quoted 67 lines
Quoted 63 lines
Quoted 54 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 2 lines
The SA lookup logic and management is purely requirement based for the
application.
Quoted 2 lines
The application may only cater to <128 SAs which can be handled based on the current logic.
Not always, current implementation can handle < 128 SA, whose SPI%128 never match (let say it cant't handle SPI=1 and SPI=129). Yes, what we have right now has nearly zero overhead,
and might be ok for some really simple show-cases.
But for majority of production IPsec implementations,
I believe that definitely wouldn't be enough.Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
–single-sa option cannot handle this.
Sample applications in DPDK are there to showcase the best a hardwarecan
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
deliver.
My thought was - that's the reason we have single-sa option - demonstrate best possible HW perf without minimal SW intervention. For something more serious than that, we use generic SAD implementation.
Quoted 2 lines
IMO, we cannot allow this logic on NXP hardwares. We give performance numbers based on IPSec app to customers and we
cannot
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
allow 15% degradation.
As Vladimir said, we are looking how to improve current SAD numbers and minimize the drop.
But with same equals - plain array will always be faster than hash table, so not sure we will be able to match existing performance.
So two questions:
1. What exact case you use for perf testing
(total number of SAs, packets per burst belong to the same/different SAs)? Might be there is a way to speedup it.
Again if 10-15% is not an affordable drop, which one is: zero or ...?Quoted 7 lines
Quoted 7 lines
We should add features judiciously, we cannot drop the performance of a benchmarking
Application in lieu of adding functionality. We should only add features which are not
Impacting the performance significantly.
Every vendor may have different cases. We cannot tune for everybody. However, I see drop in 64 outbound 64 inbound SAs all with different SPI andIPs.
Quoted 6 lines
Quoted 2 lines
Packets per burst = 32 all with different SAs.
We can have two modes of lookup similar to l3fwd - EM and LPM.
LPM is O(1) while EM is more realistic. Similar logic can be added here as well. With L3fwd also we showcase performance for best case(lpm) and the worstcase(em)
Quoted 1 line
What Say?
Quoted 8 lines
We discussed it off-line with Vladimir and came up with similar idea:
Have a proper/generic SAD implementation and add limited size plain-array on top of it as 1xway associative cache.
So for the case when all active SAs fit into the cache and no SPI collisions, we should have same performance as now (with plain array).
From other side, we'll still have generic/scalable/rfc compliant implementation. Sort of best sides from two words.
Plans are to submit v4 with such approach in next few days.Quoted 3 lines
OK lets check the v4 before moving the discussion to techboard. @Thomas: Do you have more thoughts on this? Should we get it added in the agenda Or wait for the v4?
Quoted 7 lines
If v4 is good for both cases, it lowers the priority of the discussion.
But still, it would be interesting to state the objectives of the examples:
- show API usage?
- show feature performance?
- show best hardware performance?
- what else?
Agree, that’s a good topic to discuss.
v5 cover integrate librte_ipsec SAD into ipsec-secgw
In reply to Vladimir MedvedkinThis series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
According to our measurements, after this series of patches, ipsec-secgw performance drops by about 0-2%.
v5:
- introduce SAD cache to solve performance degradation
- ipsec_sad_add() returns an error if the key is present
v4:
- put tunnel SA's into SAD with SPI_ONLY type for performance reason
v3:
- parse SA and SP into sorted array instead of linked list
v2:
- get rid of maximum sp limitation
Vladimir Medvedkin (6):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitation examples/ipsec-secgw: add SAD cache
examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 34 +++++- examples/ipsec-secgw/ipsec.h | 12 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 238 +++++++++++++++++++++---------------- examples/ipsec-secgw/sad.c | 149 +++++++++++++++++++++++ examples/ipsec-secgw/sad.h | 168 ++++++++++++++++++++++++++ examples/ipsec-secgw/sp4.c | 114 +++++++++++++----- examples/ipsec-secgw/sp6.c | 112 ++++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 ++-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 686 insertions(+), 179 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
Signature · 1 line
2.7.4
PATCH v5 1/6 ipsec: move ipsec sad name length into .h
Move IPSEC_SAD_NAMESIZE into public header
and rename it to RTE_IPSEC_SAD_NAMESIZE
--- lib/librte_ipsec/ipsec_sad.c | 20 ++++++++++---------- lib/librte_ipsec/rte_ipsec_sad.h | 2 ++ 2 files changed, 12 insertions(+), 10 deletions(-)
lib/librte_ipsec/ipsec_sad.c +10 -10
@@ -20,7 +20,6 @@* 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>" */ #define SAD_FORMAT SAD_PREFIX "%s"
@@ -34,7 +33,7 @@ struct hash_cnt { };struct rte_ipsec_sad { -char name[IPSEC_SAD_NAMESIZE ]; +char name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_hash *hash[RTE_IPSEC_SAD_KEY_TYPE_MASK ];/* Array to track number of more specific rules * (spi_dip or spi_dip_sip). Used only in add/delete
@@ -231,7 +230,7 @@ struct rte_ipsec_sad * rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf) { char hash_name[RTE_HASH_NAMESIZE]; -char sad_name[IPSEC_SAD_NAMESIZE ]; +char sad_name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_tailq_entry *te;struct rte_ipsec_sad_list *sad_list;struct rte_ipsec_sad *sad, *tmp_sad =NULL ;
@@ -249,8 +248,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)return NULL ; } - ret =snprintf (sad_name,IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); -if (ret <0 || ret >=IPSEC_SAD_NAMESIZE ) { + ret =snprintf (sad_name,RTE_IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); +if (ret <0 || ret >=RTE_IPSEC_SAD_NAMESIZE ) { rte_errno =ENAMETOOLONG ;return NULL ; }
@@ -326,7 +325,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)/* guarantee there's no existing */ TAILQ_FOREACH(te, sad_list, next) { tmp_sad = (struct rte_ipsec_sad *)te->data; -if (strncmp (sad_name, tmp_sad->name,IPSEC_SAD_NAMESIZE ) ==0 ) +if (strncmp (sad_name, tmp_sad->name, +RTE_IPSEC_SAD_NAMESIZE ) ==0 )break ; }if (te !=NULL ) {
@@ -354,14 +354,14 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)struct rte_ipsec_sad *rte_ipsec_sad_find_existing (const char *name) { -char sad_name[IPSEC_SAD_NAMESIZE ]; +char sad_name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_ipsec_sad *sad =NULL ;struct rte_tailq_entry *te;struct rte_ipsec_sad_list *sad_list;int ret; - ret =snprintf (sad_name,IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); -if (ret <0 || ret >=IPSEC_SAD_NAMESIZE ) { + ret =snprintf (sad_name,RTE_IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); +if (ret <0 || ret >=RTE_IPSEC_SAD_NAMESIZE ) { rte_errno =ENAMETOOLONG ;return NULL ; }
@@ -372,7 +372,7 @@ rte_ipsec_sad_find_existing(const char *name)rte_mcfg_tailq_read_lock (); TAILQ_FOREACH(te, sad_list, next) { sad = (struct rte_ipsec_sad *) te->data; -if (strncmp (sad_name, sad->name,IPSEC_SAD_NAMESIZE ) ==0 ) +if (strncmp (sad_name, sad->name,RTE_IPSEC_SAD_NAMESIZE ) ==0 )break ; }rte_mcfg_tailq_read_unlock ();
lib/librte_ipsec/rte_ipsec_sad.h +2 -0
@@ -47,6 +47,8 @@ union rte_ipsec_sad_key {struct rte_ipsec_sadv6_key v6; }; +/** Max number of characters in SAD name. */ +#define RTE_IPSEC_SAD_NAMESIZE 64/** Flag to create SAD with ipv6 dip and sip addresses */ #define RTE_IPSEC_SAD_FLAG_IPV6 0x1/** Flag to support reader writer concurrency */
Signature · 1 line
2.7.4
PATCH v5 2/6 examples/ipsec-secgw: implement inbound SAD
In reply to Vladimir MedvedkinAdd initial support for librte_ipsec SAD library
--- examples/ipsec-secgw/ipsec.h | 7 +++ examples/ipsec-secgw/sad.c | 109 +++++++++++++++++++++++++++++++++++++++++++ examples/ipsec-secgw/sad.h | 75 +++++++++++++++++++++++++++++ 3 files changed, 191 insertions(+) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
examples/ipsec-secgw/ipsec.h +7 -0
@@ -53,6 +53,13 @@ struct ipsec_xform;struct rte_mbuf ;struct ipsec_sa ; +/* +* Keeps number of configured SA's for each address family: +*/ +struct ipsec_sa_cnt { +uint32_t nb_v4; +uint32_t nb_v6; +};typedef int32_t (*ipsec_xform_fn )(struct rte_mbuf *m,struct ipsec_sa *sa,struct rte_crypto_op *cop);
examples/ipsec-secgw/sad.c new file +109 -0
109 lines not on this page · raw message
examples/ipsec-secgw/sad.h new file +75 -0
75 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v5 3/6 examples/ipsec-secgw: integrate inbound SAD
In reply to Vladimir MedvedkinIntegrate ipsec SAD support into secgw app:
1. Use SAD library for inbound SA lookup
2. Changes in struct sa_ctx:
- sa array allocates dynamically depending on number of configured sa
- All SA's are kept one by one without using SPI2IDX
3. SP's userdata now contain index of SA in sa_ctx instead of SPI
4. Get rid of SPI2IDX macro
--- examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 3 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/sa.c | 182 +++++++++++++++++++++---------------- examples/ipsec-secgw/sp4.c | 24 +++-- examples/ipsec-secgw/sp6.c | 24 +++-- 7 files changed, 139 insertions(+), 101 deletions(-)
examples/ipsec-secgw/Makefile +1 -0
@@ -12,6 +12,7 @@ SRCS-y += esp.c SRCS-y += sp4.c SRCS-y += sp6.c SRCS-y += sa.c +SRCS-y += sad.c SRCS-y += rt.c SRCS-y += ipsec_process.c SRCS-y += ipsec-secgw.c
examples/ipsec-secgw/ipsec-secgw.c +2 -2
@@ -601,7 +601,7 @@ inbound_sp_sa(struct sp_ctx *sp, struct sa_ctx *sa, struct traffic_type *ip,continue ; } - sa_idx =SPI2IDX (res); + sa_idx = res -1 ;if (!inbound_sa_check (sa, m, sa_idx)) {rte_pktmbuf_free (m);continue ;
@@ -688,7 +688,7 @@ outbound_sp(struct sp_ctx *sp, struct traffic_type *ip, j =0 ;for (i =0 ; i < ip->num; i++) { m = ip->pkts[i]; - sa_idx =SPI2IDX (ip->res[i]); + sa_idx = ip->res[i] -1 ;if (ip->res[i] ==DISCARD )rte_pktmbuf_free (m);else if (ip->res[i] ==BYPASS )
examples/ipsec-secgw/ipsec.h +1 -2
@@ -38,7 +38,6 @@#define DEFAULT_MAX_CATEGORIES 1#define IPSEC_SA_MAX_ENTRIES (128)/* must be power of 2, max 2 power 30 */ -#define SPI2IDX (spi) (spi & (IPSEC_SA_MAX_ENTRIES - 1))#define INVALID_SPI (0)#define DISCARD INVALID_SPI
@@ -359,7 +358,7 @@ sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],* or -ENOENT otherwise. */ int -sa_spi_present (uint32_t spi,int inbound); +sa_spi_present (struct sa_ctx *sa_ctx,uint32_t spi,int inbound);void sa_init (struct socket_ctx *ctx,int32_t socket_id);
examples/ipsec-secgw/meson.build +1 -1
@@ -10,5 +10,5 @@ deps += ['security', 'lpm', 'acl', 'hash', 'ip_frag', 'ipsec'] allow_experimental_apis = true sources = files( 'esp.c', 'ipsec.c', 'ipsec_process.c', 'ipsec-secgw.c', - 'parser.c', 'rt.c', 'sa.c', 'sp4.c', 'sp6.c' + 'parser.c', 'rt.c', 'sa.c', 'sad.c', 'sp4.c', 'sp6.c' )
examples/ipsec-secgw/sa.c +104 -78
343 lines not on this page · raw message
examples/ipsec-secgw/sp4.c +15 -9
@@ -493,10 +493,11 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules,* check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value (int inbound) +check_spi_value (struct sa_ctx *sa_ctx,int inbound) {uint32_t i, num, spi; -const struct acl4_rules *acr; +int32_t spi_idx; +struct acl4_rules *acr;if (inbound !=0 ) { acr = acl4_rules_in;
@@ -508,11 +509,16 @@ check_spi_value(int inbound)for (i =0 ; i != num; i++) { spi = acr[i].data.userdata; -if (spi !=DISCARD && spi !=BYPASS && -sa_spi_present (spi, inbound) <0 ) { -RTE_LOG (ERR ,IPSEC ,"SPI %u is not present in SAD\n" , - spi); -return -ENOENT ; +if (spi !=DISCARD && spi !=BYPASS ) { + spi_idx =sa_spi_present (sa_ctx, spi, inbound); +if (spi_idx <0 ) { +RTE_LOG (ERR ,IPSEC , +"SPI %u is not present in SAD\n" , + spi); +return -ENOENT ; + } +/* Update userdata with spi index */ + acr[i].data.userdata = spi_idx +1 ; } }
@@ -535,11 +541,11 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id)rte_exit (EXIT_FAILURE ,"Outbound SP DB for socket %u already " "initialized\n" , socket_id); -if (check_spi_value (1 ) <0 ) +if (check_spi_value (ctx->sa_in,1 ) <0 )rte_exit (EXIT_FAILURE ,"Inbound IPv4 SP DB has unmatched in SAD SPIs\n" ); -if (check_spi_value (0 ) <0 ) +if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv4 SP DB has unmatched in SAD SPIs\n" );
examples/ipsec-secgw/sp6.c +15 -9
@@ -625,10 +625,11 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_rules *rules,* check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value (int inbound) +check_spi_value (struct sa_ctx *sa_ctx,int inbound) {uint32_t i, num, spi; -const struct acl6_rules *acr; +int32_t spi_idx; +struct acl6_rules *acr;if (inbound !=0 ) { acr = acl6_rules_in;
@@ -640,11 +641,16 @@ check_spi_value(int inbound)for (i =0 ; i != num; i++) { spi = acr[i].data.userdata; -if (spi !=DISCARD && spi !=BYPASS && -sa_spi_present (spi, inbound) <0 ) { -RTE_LOG (ERR ,IPSEC ,"SPI %u is not present in SAD\n" , - spi); -return -ENOENT ; +if (spi !=DISCARD && spi !=BYPASS ) { + spi_idx =sa_spi_present (sa_ctx, spi, inbound); +if (spi_idx <0 ) { +RTE_LOG (ERR ,IPSEC , +"SPI %u is not present in SAD\n" , + spi); +return -ENOENT ; + } +/* Update userdata with spi index */ + acr[i].data.userdata = spi_idx +1 ; } }
@@ -667,11 +673,11 @@ sp6_init(struct socket_ctx *ctx, int32_t socket_id)rte_exit (EXIT_FAILURE ,"Outbound IPv6 SP DB for socket %u " "already initialized\n" , socket_id); -if (check_spi_value (1 ) <0 ) +if (check_spi_value (ctx->sa_in,1 ) <0 )rte_exit (EXIT_FAILURE ,"Inbound IPv6 SP DB has unmatched in SAD SPIs\n" ); -if (check_spi_value (0 ) <0 ) +if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv6 SP DB has unmatched in SAD SPIs\n" );
Signature · 1 line
2.7.4
PATCH v5 4/6 examples/ipsec-secgw: get rid of maximum sa limitation
In reply to Vladimir MedvedkinGet rid of maximum SA limitation.
Keep parsed SA's into the sorted by SPI value array. Use binary search in the sorted SA array to find appropriate SA for a given SPI.
--- examples/ipsec-secgw/ipsec.h | 1 - examples/ipsec-secgw/parser.c | 2 ++ examples/ipsec-secgw/parser.h | 3 ++ examples/ipsec-secgw/sa.c | 74 +++++++++++++++++++++++++++++++++---------- 4 files changed, 62 insertions(+), 18 deletions(-)
examples/ipsec-secgw/ipsec.h +0 -1
@@ -37,7 +37,6 @@#define DEFAULT_MAX_CATEGORIES 1 -#define IPSEC_SA_MAX_ENTRIES (128)/* must be power of 2, max 2 power 30 */ #define INVALID_SPI (0)#define DISCARD INVALID_SPI
examples/ipsec-secgw/parser.c +2 -0
@@ -642,6 +642,8 @@ parse_cfg_file(const char *cfg_filename)cmdline_stdin_exit (cl);fclose (f); +sa_sort_arr (); +return 0 ; error_exit:
examples/ipsec-secgw/parser.h +3 -0
@@ -75,6 +75,9 @@ parse_sp6_tokens(char **tokens, uint32_t n_tokens, struct parse_status *status);void +sa_sort_arr (void ); + +void parse_sa_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status);
examples/ipsec-secgw/sa.c +57 -17
123 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v5 5/6 examples/ipsec-secgw: get rid of maximum sp limitation
In reply to Vladimir MedvedkinGet rid of maximum SP limitation.
Keep parsed SP's into the sorted by SPI value array. Use binary search in the sorted SP array to find appropriate SP for a given SPI.
--- examples/ipsec-secgw/parser.c | 2 + examples/ipsec-secgw/parser.h | 6 +++ examples/ipsec-secgw/sp4.c | 90 +++++++++++++++++++++++++++++++++---------- examples/ipsec-secgw/sp6.c | 88 ++++++++++++++++++++++++++++++++---------- 4 files changed, 144 insertions(+), 42 deletions(-)
examples/ipsec-secgw/parser.c +2 -0
@@ -643,6 +643,8 @@ parse_cfg_file(const char *cfg_filename)fclose (f);sa_sort_arr (); +sp4_sort_arr (); +sp6_sort_arr ();return 0 ;
examples/ipsec-secgw/parser.h +6 -0
@@ -67,10 +67,16 @@ int parse_range(const char *token, uint16_t *low, uint16_t *high);void +sp4_sort_arr (void ); + +void parse_sp4_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status);void +sp6_sort_arr (void ); + +void parse_sp6_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status);
examples/ipsec-secgw/sp4.c +69 -21
150 lines not on this page · raw message
examples/ipsec-secgw/sp6.c +67 -21
148 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v5 6/6 examples/ipsec-secgw: add SAD cache
In reply to Vladimir MedvedkinIntroduce SAD cache.
Stores the most recent SA in a per lcore cache. Cache represents flat array containing SA's indexed by SPI.
--- examples/ipsec-secgw/ipsec-secgw.c | 30 +++++++++- examples/ipsec-secgw/ipsec.h | 1 + examples/ipsec-secgw/sa.c | 32 +---------- examples/ipsec-secgw/sad.c | 40 ++++++++++++++ examples/ipsec-secgw/sad.h | 109 ++++++++++++++++++++++++++++++++++--- 5 files changed, 171 insertions(+), 41 deletions(-)
examples/ipsec-secgw/ipsec-secgw.c +27 -3
@@ -46,6 +46,7 @@#include "ipsec.h" #include "parser.h" +#include "sad.h" #define RTE_LOGTYPE_IPSEC RTE_LOGTYPE_USER1
@@ -192,7 +193,10 @@ static uint32_t mtu_size = RTE_ETHER_MTU;static uint64_t frag_ttl_ns =MAX_FRAG_TTL_NS ;/* application wide librte_ipsec/SA parameters */ -struct app_sa_prm app_sa_prm = {.enable =0 }; +struct app_sa_prm app_sa_prm = { + .enable =0 , + .cache_sz =SA_CACHE_SZ + };static const char *cfgfile;struct lcore_rx_queue {
@@ -1102,7 +1106,7 @@ main_loop(__attribute__((unused)) void *dummy)uint16_t portid;uint8_t queueid;struct lcore_conf *qconf; -int32_t socket_id; +int32_t rc, socket_id;const uint64_t drain_tsc = (rte_get_tsc_hz () +US_PER_S -1 ) /US_PER_S *BURST_TX_DRAIN_US ;struct lcore_rx_queue *rxql;
@@ -1132,6 +1136,14 @@ main_loop(__attribute__((unused)) void *dummy) qconf->frag.pool_dir = socket_ctx[socket_id].mbuf_pool; qconf->frag.pool_indir = socket_ctx[socket_id].mbuf_pool_indir; + rc =ipsec_sad_lcore_cache_init (app_sa_prm.cache_sz); +if (rc !=0 ) { +RTE_LOG (ERR ,IPSEC , +"SAD cache init on lcore %u, failed with code: %d\n" , + lcore_id, rc); +return rc; + } +if (qconf->nb_rx_queue ==0 ) {RTE_LOG (DEBUG ,IPSEC ,"lcore %u has nothing to do\n" , lcore_id);
@@ -1271,6 +1283,7 @@ print_usage(const char *prgname)" [-w REPLAY_WINDOW_SIZE]" " [-e]" " [-a]" +" [-c]" " -f CONFIG_FILE" " --config (port,queue,lcore)[,(port,queue,lcore)]" " [--single-sa SAIDX]"
@@ -1290,6 +1303,8 @@ print_usage(const char *prgname)" size for each SA\n" " -e enables ESN\n" " -a enables SA SQN atomic behaviour\n" +" -c specifies inbound SAD cache size,\n" +" zero value disables the cache (default value: 128)\n" " -f CONFIG_FILE: Configuration file\n" " --config (port,queue,lcore): Rx queue configuration\n" " --single-sa SAIDX: Use single SA index for outbound traffic,\n"
@@ -1442,7 +1457,7 @@ parse_args(int32_t argc, char **argv) argvopt = argv; -while ((opt =getopt_long (argc, argvopt,"aelp:Pu:f:j:w:" , +while ((opt =getopt_long (argc, argvopt,"aelp:Pu:f:j:w:c:" , lgopts, &option_index)) !=EOF ) {switch (opt) {
@@ -1501,6 +1516,15 @@ parse_args(int32_t argc, char **argv) app_sa_prm.enable =1 ; app_sa_prm.flags |=RTE_IPSEC_SAFLAG_SQN_ATOM ;break ; +case 'c' : + ret =parse_decimal (optarg); +if (ret <0 ) { +printf ("Invalid SA cache size: %s\n" , optarg); +print_usage (prgname); +return -1 ; + } + app_sa_prm.cache_sz = ret; +break ;case CMD_LINE_OPT_CONFIG_NUM : ret =parse_config (optarg);if (ret) {
examples/ipsec-secgw/ipsec.h +1 -0
@@ -81,6 +81,7 @@ struct app_sa_prm {uint32_t enable;/* use librte_ipsec API for ipsec pkt processing */ uint32_t window_size;/* replay window size */ uint32_t enable_esn;/* enable/disable ESN support */ +uint32_t cache_sz;/* per lcore SA cache size */ uint64_t flags;/* rte_ipsec_sa_prm.flags */ };
examples/ipsec-secgw/sa.c +2 -30
@@ -839,7 +839,7 @@ sa_create(const char *name, int32_t socket_id, uint32_t nb_sa)return NULL ; } - sa_ctx =rte_malloc (NULL ,sizeof (struct sa_ctx ) + + sa_ctx =rte_zmalloc (NULL ,sizeof (struct sa_ctx ) +sizeof (struct ipsec_sa ) * nb_sa,RTE_CACHE_LINE_SIZE );if (sa_ctx ==NULL ) {
@@ -1451,9 +1451,6 @@ inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[], void *sa_arr[], uint16_t nb_pkts) {uint32_t i; -struct ip *ip; -uint32_t *src4_addr; -uint8_t *src6_addr;void *result_sa;struct ipsec_sa *sa;
@@ -1479,32 +1476,7 @@ inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[], intsa |=IPSEC_SA_OFFLOAD_FALLBACK_FLAG ; result_sa = (void *)intsa; } - - ip = rte_pktmbuf_mtod(pkts[i], struct ip *); -switch (WITHOUT_TRANSPORT_VERSION (sa->flags)) { -case IP4_TUNNEL : - src4_addr =RTE_PTR_ADD (ip, - offsetof(struct ip , ip_src)); -if ((ip->ip_v ==IPVERSION ) && - (sa->src.ip.ip4 == *src4_addr) && - (sa->dst.ip.ip4 == *(src4_addr +1 ))) - sa_arr[i] = result_sa; -else - sa_arr[i] =NULL ; -break ; -case IP6_TUNNEL : - src6_addr =RTE_PTR_ADD (ip, - offsetof(struct ip6_hdr , ip6_src)); -if ((ip->ip_v ==IP6_VERSION ) && - !memcmp (&sa->src.ip.ip6.ip6, src6_addr,16 ) && - !memcmp (&sa->dst.ip.ip6.ip6, src6_addr +16 ,16 )) - sa_arr[i] = result_sa; -else - sa_arr[i] =NULL ; -break ; -case TRANSPORT : - sa_arr[i] = result_sa; - } + sa_arr[i] = result_sa; } }
examples/ipsec-secgw/sad.c +40 -0
@@ -3,10 +3,17 @@*/ #include <rte_errno.h> +#include <rte_malloc.h> #include "ipsec.h" #include "sad.h" +RTE_DEFINE_PER_LCORE(struct ipsec_sad_cache, sad_cache) = { + .v4 =NULL , + .v6 =NULL , + .mask =0 , +}; +int ipsec_sad_add (struct ipsec_sad *sad,struct ipsec_sa *sa) {
@@ -65,6 +72,39 @@ ipsec_sad_add(struct ipsec_sad *sad, struct ipsec_sa *sa)return 0 ; } +/* +* Init per lcore SAD cache. +* Must be called by every processing lcore. +*/ +int +ipsec_sad_lcore_cache_init (uint32_t nb_cache_ent) +{ +uint32_t cache_elem; +size_t cache_mem_sz; +struct ipsec_sad_cache *cache; + + cache = &RTE_PER_LCORE (sad_cache); + + cache_elem =rte_align32pow2 (nb_cache_ent); + cache_mem_sz =sizeof (struct ipsec_sa *) * cache_elem; + +if (cache_mem_sz !=0 ) { + cache->v4 =rte_zmalloc_socket (NULL , cache_mem_sz, +RTE_CACHE_LINE_SIZE ,rte_socket_id ()); +if (cache->v4 ==NULL ) +return -rte_errno; + + cache->v6 =rte_zmalloc_socket (NULL , cache_mem_sz, +RTE_CACHE_LINE_SIZE ,rte_socket_id ()); +if (cache->v6 ==NULL ) +return -rte_errno; + + cache->mask = cache_elem -1 ; + } + +return 0 ; +} +int ipsec_sad_create (const char *name,struct ipsec_sad *sad,int socket_id,struct ipsec_sa_cnt *sa_cnt)
examples/ipsec-secgw/sad.h +101 -8
146 lines not on this page · raw message
Signature · 1 line
2.7.4
Quoted 30 lines
This series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
According to our measurements, after this series of patches, ipsec-secgw performance drops by about 0-2%.v5:
- introduce SAD cache to solve performance degradation
-ipsec_sad_add()returns an error if the key is presentv4:
- put tunnel SA's into SAD withSPI_ONLYtype for performance reasonv3:
- parse SA and SP into sorted array instead of linked listv2:
- get rid of maximum sp limitationVladimir Medvedkin (6):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitation examples/ipsec-secgw: add SAD cache
Quoted 17 lines
examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 34 +++++- examples/ipsec-secgw/ipsec.h | 12 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 238 +++++++++++++++++++++---------------- examples/ipsec-secgw/sad.c | 149 +++++++++++++++++++++++ examples/ipsec-secgw/sad.h | 168 ++++++++++++++++++++++++++ examples/ipsec-secgw/sp4.c | 114 +++++++++++++----- examples/ipsec-secgw/sp6.c | 112 ++++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 ++-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 686 insertions(+), 179 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
Series
Hi Anoob,
Do you have any comments on this set. I do not see degradation on this patchset now.
Regards,
Akhil
Anoob Joseph
Acked-byHi Akhil,
Quoted 48 lines
Quoted 29 lines
This series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
According to our measurements, after this series of patches, ipsec-secgw performance drops by about 0-2%.v5:
- introduce SAD cache to solve performance degradation
-ipsec_sad_add()returns an error if the key is presentv4:
- put tunnel SA's into SAD withSPI_ONLYtype for performance reasonv3:
- parse SA and SP into sorted array instead of linked listv2:
- get rid of maximum sp limitationVladimir Medvedkin (6):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitation examples/ipsec-secgw: add SAD cacheQuoted 7 lines
examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 34 +++++- examples/ipsec-secgw/ipsec.h | 12 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 238 +++++++++++++++++++++----------------
Quoted 10 lines
examples/ipsec-secgw/sad.c | 149 +++++++++++++++++++++++ examples/ipsec-secgw/sad.h | 168 ++++++++++++++++++++++++++ examples/ipsec-secgw/sp4.c | 114 +++++++++++++----- examples/ipsec-secgw/sp6.c | 112 ++++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 ++-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 686 insertions(+), 179 deletions(-) create mode100644
examples/ipsec-secgw/sad.ccreate mode 100644examples/ipsec-secgw/sad.h
Quoted 7 lines
Series
Acked-by Akhil Goyal <[email protected]>Hi Anoob,
Do you have any comments on this set. I do not see degradation on this patchset now.
[Anoob] The perf degradation is negligible on our platform as well. I don't have any issue with the patch set.
Series
Akhil Goyal
AppliedQuoted 56 lines
Hi Akhil,
Quoted 53 lines
Quoted 29 lines
This series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
According to our measurements, after this series of patches, ipsec-secgw performance drops by about 0-2%.v5:
- introduce SAD cache to solve performance degradation
-ipsec_sad_add()returns an error if the key is presentv4:
- put tunnel SA's into SAD withSPI_ONLYtype for performance reasonv3:
- parse SA and SP into sorted array instead of linked listv2:
- get rid of maximum sp limitationVladimir Medvedkin (6):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitation examples/ipsec-secgw: add SAD cacheQuoted 7 lines
examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 34 +++++- examples/ipsec-secgw/ipsec.h | 12 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 238 +++++++++++++++++++++----------------
Quoted 10 lines
examples/ipsec-secgw/sad.c | 149 +++++++++++++++++++++++ examples/ipsec-secgw/sad.h | 168 ++++++++++++++++++++++++++ examples/ipsec-secgw/sp4.c | 114 +++++++++++++----- examples/ipsec-secgw/sp6.c | 112 ++++++++++++----- lib/librte_ipsec/ipsec_sad.c | 20 ++-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 13 files changed, 686 insertions(+), 179 deletions(-) create mode100644
examples/ipsec-secgw/sad.ccreate mode 100644examples/ipsec-secgw/sad.hSeries
Acked-by Akhil Goyal <[email protected]>Hi Anoob,
Quoted 8 lines
Quoted 2 lines
Do you have any comments on this set. I do not see degradation on this patchset now.
[Anoob] The perf degradation is negligible on our platform as well. I don't have any issue with the patch set.
Series
Acked-by Anoob Joseph <[email protected]>
Applied to dpdk-next-crypto
Thanks.
v6 cover integrate librte_ipsec SAD into ipsec-secgw
In reply to Vladimir MedvedkinThis series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
According to our measurements, after this series of patches, ipsec-secgw performance drops by about 0-2%.
v6:
- add SA check for NULL pointer after rte_ipsec_sad_lookup()
- using mbuf ptype field to distinguish v4 and v6 packets
- add SAD cache size option into documentation
v5:
- introduce SAD cache to solve performance degradation
- ipsec_sad_add() returns an error if the key is present
v4:
- put tunnel SA's into SAD with SPI_ONLY type for performance reason
v3:
- parse SA and SP into sorted array instead of linked list
v2:
- get rid of maximum sp limitation
Vladimir Medvedkin (8):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitation examples/ipsec-secgw: add SAD cache examples/ipsec-secgw: set/use mbuf ptype
doc: update ipsec-secgw guide
doc/guides/sample_app_ug/ipsec_secgw.rst | 6 + examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 36 ++++- examples/ipsec-secgw/ipsec.h | 12 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 238 ++++++++++++++++++------------- examples/ipsec-secgw/sad.c | 149 +++++++++++++++++++ examples/ipsec-secgw/sad.h | 170 ++++++++++++++++++++++ examples/ipsec-secgw/sp4.c | 114 +++++++++++---- examples/ipsec-secgw/sp6.c | 112 +++++++++++---- lib/librte_ipsec/ipsec_sad.c | 20 +-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 14 files changed, 696 insertions(+), 179 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
Signature · 1 line
2.7.4
PATCH v6 1/8 ipsec: move ipsec sad name length into .h
Move IPSEC_SAD_NAMESIZE into public header
and rename it to RTE_IPSEC_SAD_NAMESIZE
--- lib/librte_ipsec/ipsec_sad.c | 20 ++++++++++---------- lib/librte_ipsec/rte_ipsec_sad.h | 2 ++ 2 files changed, 12 insertions(+), 10 deletions(-)
lib/librte_ipsec/ipsec_sad.c +10 -10
@@ -20,7 +20,6 @@* 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>" */ #define SAD_FORMAT SAD_PREFIX "%s"
@@ -34,7 +33,7 @@ struct hash_cnt { };struct rte_ipsec_sad { -char name[IPSEC_SAD_NAMESIZE ]; +char name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_hash *hash[RTE_IPSEC_SAD_KEY_TYPE_MASK ];/* Array to track number of more specific rules * (spi_dip or spi_dip_sip). Used only in add/delete
@@ -231,7 +230,7 @@ struct rte_ipsec_sad * rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf) { char hash_name[RTE_HASH_NAMESIZE]; -char sad_name[IPSEC_SAD_NAMESIZE ]; +char sad_name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_tailq_entry *te;struct rte_ipsec_sad_list *sad_list;struct rte_ipsec_sad *sad, *tmp_sad =NULL ;
@@ -249,8 +248,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)return NULL ; } - ret =snprintf (sad_name,IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); -if (ret <0 || ret >=IPSEC_SAD_NAMESIZE ) { + ret =snprintf (sad_name,RTE_IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); +if (ret <0 || ret >=RTE_IPSEC_SAD_NAMESIZE ) { rte_errno =ENAMETOOLONG ;return NULL ; }
@@ -326,7 +325,8 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)/* guarantee there's no existing */ TAILQ_FOREACH(te, sad_list, next) { tmp_sad = (struct rte_ipsec_sad *)te->data; -if (strncmp (sad_name, tmp_sad->name,IPSEC_SAD_NAMESIZE ) ==0 ) +if (strncmp (sad_name, tmp_sad->name, +RTE_IPSEC_SAD_NAMESIZE ) ==0 )break ; }if (te !=NULL ) {
@@ -354,14 +354,14 @@ rte_ipsec_sad_create(const char *name, const struct rte_ipsec_sad_conf *conf)struct rte_ipsec_sad *rte_ipsec_sad_find_existing (const char *name) { -char sad_name[IPSEC_SAD_NAMESIZE ]; +char sad_name[RTE_IPSEC_SAD_NAMESIZE ];struct rte_ipsec_sad *sad =NULL ;struct rte_tailq_entry *te;struct rte_ipsec_sad_list *sad_list;int ret; - ret =snprintf (sad_name,IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); -if (ret <0 || ret >=IPSEC_SAD_NAMESIZE ) { + ret =snprintf (sad_name,RTE_IPSEC_SAD_NAMESIZE ,SAD_FORMAT , name); +if (ret <0 || ret >=RTE_IPSEC_SAD_NAMESIZE ) { rte_errno =ENAMETOOLONG ;return NULL ; }
@@ -372,7 +372,7 @@ rte_ipsec_sad_find_existing(const char *name)rte_mcfg_tailq_read_lock (); TAILQ_FOREACH(te, sad_list, next) { sad = (struct rte_ipsec_sad *) te->data; -if (strncmp (sad_name, sad->name,IPSEC_SAD_NAMESIZE ) ==0 ) +if (strncmp (sad_name, sad->name,RTE_IPSEC_SAD_NAMESIZE ) ==0 )break ; }rte_mcfg_tailq_read_unlock ();
lib/librte_ipsec/rte_ipsec_sad.h +2 -0
@@ -47,6 +47,8 @@ union rte_ipsec_sad_key {struct rte_ipsec_sadv6_key v6; }; +/** Max number of characters in SAD name. */ +#define RTE_IPSEC_SAD_NAMESIZE 64/** Flag to create SAD with ipv6 dip and sip addresses */ #define RTE_IPSEC_SAD_FLAG_IPV6 0x1/** Flag to support reader writer concurrency */
Signature · 1 line
2.7.4
PATCH v6 2/8 examples/ipsec-secgw: implement inbound SAD
In reply to Vladimir MedvedkinAdd initial support for librte_ipsec SAD library
--- examples/ipsec-secgw/ipsec.h | 7 +++ examples/ipsec-secgw/sad.c | 109 +++++++++++++++++++++++++++++++++++++++++++ examples/ipsec-secgw/sad.h | 75 +++++++++++++++++++++++++++++ 3 files changed, 191 insertions(+) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
examples/ipsec-secgw/ipsec.h +7 -0
@@ -53,6 +53,13 @@ struct ipsec_xform;struct rte_mbuf ;struct ipsec_sa ; +/* +* Keeps number of configured SA's for each address family: +*/ +struct ipsec_sa_cnt { +uint32_t nb_v4; +uint32_t nb_v6; +};typedef int32_t (*ipsec_xform_fn )(struct rte_mbuf *m,struct ipsec_sa *sa,struct rte_crypto_op *cop);
examples/ipsec-secgw/sad.c new file +109 -0
109 lines not on this page · raw message
examples/ipsec-secgw/sad.h new file +75 -0
75 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v6 3/8 examples/ipsec-secgw: integrate inbound SAD
In reply to Vladimir MedvedkinIntegrate ipsec SAD support into secgw app:
1. Use SAD library for inbound SA lookup
2. Changes in struct sa_ctx:
- sa array allocates dynamically depending on number of configured sa
- All SA's are kept one by one without using SPI2IDX
3. SP's userdata now contain index of SA in sa_ctx instead of SPI
4. Get rid of SPI2IDX macro
--- examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 4 +- examples/ipsec-secgw/ipsec.h | 3 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/sa.c | 182 +++++++++++++++++++++---------------- examples/ipsec-secgw/sp4.c | 24 +++-- examples/ipsec-secgw/sp6.c | 24 +++-- 7 files changed, 139 insertions(+), 101 deletions(-)
examples/ipsec-secgw/Makefile +1 -0
@@ -12,6 +12,7 @@ SRCS-y += esp.c SRCS-y += sp4.c SRCS-y += sp6.c SRCS-y += sa.c +SRCS-y += sad.c SRCS-y += rt.c SRCS-y += ipsec_process.c SRCS-y += ipsec-secgw.c
examples/ipsec-secgw/ipsec-secgw.c +2 -2
@@ -601,7 +601,7 @@ inbound_sp_sa(struct sp_ctx *sp, struct sa_ctx *sa, struct traffic_type *ip,continue ; } - sa_idx =SPI2IDX (res); + sa_idx = res -1 ;if (!inbound_sa_check (sa, m, sa_idx)) {rte_pktmbuf_free (m);continue ;
@@ -688,7 +688,7 @@ outbound_sp(struct sp_ctx *sp, struct traffic_type *ip, j =0 ;for (i =0 ; i < ip->num; i++) { m = ip->pkts[i]; - sa_idx =SPI2IDX (ip->res[i]); + sa_idx = ip->res[i] -1 ;if (ip->res[i] ==DISCARD )rte_pktmbuf_free (m);else if (ip->res[i] ==BYPASS )
examples/ipsec-secgw/ipsec.h +1 -2
@@ -38,7 +38,6 @@#define DEFAULT_MAX_CATEGORIES 1#define IPSEC_SA_MAX_ENTRIES (128)/* must be power of 2, max 2 power 30 */ -#define SPI2IDX (spi) (spi & (IPSEC_SA_MAX_ENTRIES - 1))#define INVALID_SPI (0)#define DISCARD INVALID_SPI
@@ -359,7 +358,7 @@ sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],* or -ENOENT otherwise. */ int -sa_spi_present (uint32_t spi,int inbound); +sa_spi_present (struct sa_ctx *sa_ctx,uint32_t spi,int inbound);void sa_init (struct socket_ctx *ctx,int32_t socket_id);
examples/ipsec-secgw/meson.build +1 -1
@@ -10,5 +10,5 @@ deps += ['security', 'lpm', 'acl', 'hash', 'ip_frag', 'ipsec'] allow_experimental_apis = true sources = files( 'esp.c', 'ipsec.c', 'ipsec_process.c', 'ipsec-secgw.c', - 'parser.c', 'rt.c', 'sa.c', 'sp4.c', 'sp6.c' + 'parser.c', 'rt.c', 'sa.c', 'sad.c', 'sp4.c', 'sp6.c' )
examples/ipsec-secgw/sa.c +104 -78
343 lines not on this page · raw message
examples/ipsec-secgw/sp4.c +15 -9
@@ -493,10 +493,11 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules,* check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value (int inbound) +check_spi_value (struct sa_ctx *sa_ctx,int inbound) {uint32_t i, num, spi; -const struct acl4_rules *acr; +int32_t spi_idx; +struct acl4_rules *acr;if (inbound !=0 ) { acr = acl4_rules_in;
@@ -508,11 +509,16 @@ check_spi_value(int inbound)for (i =0 ; i != num; i++) { spi = acr[i].data.userdata; -if (spi !=DISCARD && spi !=BYPASS && -sa_spi_present (spi, inbound) <0 ) { -RTE_LOG (ERR ,IPSEC ,"SPI %u is not present in SAD\n" , - spi); -return -ENOENT ; +if (spi !=DISCARD && spi !=BYPASS ) { + spi_idx =sa_spi_present (sa_ctx, spi, inbound); +if (spi_idx <0 ) { +RTE_LOG (ERR ,IPSEC , +"SPI %u is not present in SAD\n" , + spi); +return -ENOENT ; + } +/* Update userdata with spi index */ + acr[i].data.userdata = spi_idx +1 ; } }
@@ -535,11 +541,11 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id)rte_exit (EXIT_FAILURE ,"Outbound SP DB for socket %u already " "initialized\n" , socket_id); -if (check_spi_value (1 ) <0 ) +if (check_spi_value (ctx->sa_in,1 ) <0 )rte_exit (EXIT_FAILURE ,"Inbound IPv4 SP DB has unmatched in SAD SPIs\n" ); -if (check_spi_value (0 ) <0 ) +if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv4 SP DB has unmatched in SAD SPIs\n" );
examples/ipsec-secgw/sp6.c +15 -9
@@ -625,10 +625,11 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_rules *rules,* check that for each rule it's SPI has a correspondent entry in SAD */ static int -check_spi_value (int inbound) +check_spi_value (struct sa_ctx *sa_ctx,int inbound) {uint32_t i, num, spi; -const struct acl6_rules *acr; +int32_t spi_idx; +struct acl6_rules *acr;if (inbound !=0 ) { acr = acl6_rules_in;
@@ -640,11 +641,16 @@ check_spi_value(int inbound)for (i =0 ; i != num; i++) { spi = acr[i].data.userdata; -if (spi !=DISCARD && spi !=BYPASS && -sa_spi_present (spi, inbound) <0 ) { -RTE_LOG (ERR ,IPSEC ,"SPI %u is not present in SAD\n" , - spi); -return -ENOENT ; +if (spi !=DISCARD && spi !=BYPASS ) { + spi_idx =sa_spi_present (sa_ctx, spi, inbound); +if (spi_idx <0 ) { +RTE_LOG (ERR ,IPSEC , +"SPI %u is not present in SAD\n" , + spi); +return -ENOENT ; + } +/* Update userdata with spi index */ + acr[i].data.userdata = spi_idx +1 ; } }
@@ -667,11 +673,11 @@ sp6_init(struct socket_ctx *ctx, int32_t socket_id)rte_exit (EXIT_FAILURE ,"Outbound IPv6 SP DB for socket %u " "already initialized\n" , socket_id); -if (check_spi_value (1 ) <0 ) +if (check_spi_value (ctx->sa_in,1 ) <0 )rte_exit (EXIT_FAILURE ,"Inbound IPv6 SP DB has unmatched in SAD SPIs\n" ); -if (check_spi_value (0 ) <0 ) +if (check_spi_value (ctx->sa_out,0 ) <0 )rte_exit (EXIT_FAILURE ,"Outbound IPv6 SP DB has unmatched in SAD SPIs\n" );
Signature · 1 line
2.7.4
PATCH v6 4/8 examples/ipsec-secgw: get rid of maximum sa limitation
In reply to Vladimir MedvedkinGet rid of maximum SA limitation.
Keep parsed SA's into the sorted by SPI value array. Use binary search in the sorted SA array to find appropriate SA for a given SPI.
--- examples/ipsec-secgw/ipsec.h | 1 - examples/ipsec-secgw/parser.c | 2 ++ examples/ipsec-secgw/parser.h | 3 ++ examples/ipsec-secgw/sa.c | 74 +++++++++++++++++++++++++++++++++---------- 4 files changed, 62 insertions(+), 18 deletions(-)
examples/ipsec-secgw/ipsec.h +0 -1
@@ -37,7 +37,6 @@#define DEFAULT_MAX_CATEGORIES 1 -#define IPSEC_SA_MAX_ENTRIES (128)/* must be power of 2, max 2 power 30 */ #define INVALID_SPI (0)#define DISCARD INVALID_SPI
examples/ipsec-secgw/parser.c +2 -0
@@ -642,6 +642,8 @@ parse_cfg_file(const char *cfg_filename)cmdline_stdin_exit (cl);fclose (f); +sa_sort_arr (); +return 0 ; error_exit:
examples/ipsec-secgw/parser.h +3 -0
@@ -75,6 +75,9 @@ parse_sp6_tokens(char **tokens, uint32_t n_tokens, struct parse_status *status);void +sa_sort_arr (void ); + +void parse_sa_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status);
examples/ipsec-secgw/sa.c +57 -17
123 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v6 5/8 examples/ipsec-secgw: get rid of maximum sp limitation
In reply to Vladimir MedvedkinGet rid of maximum SP limitation.
Keep parsed SP's into the sorted by SPI value array. Use binary search in the sorted SP array to find appropriate SP for a given SPI.
--- examples/ipsec-secgw/parser.c | 2 + examples/ipsec-secgw/parser.h | 6 +++ examples/ipsec-secgw/sp4.c | 90 +++++++++++++++++++++++++++++++++---------- examples/ipsec-secgw/sp6.c | 88 ++++++++++++++++++++++++++++++++---------- 4 files changed, 144 insertions(+), 42 deletions(-)
examples/ipsec-secgw/parser.c +2 -0
@@ -643,6 +643,8 @@ parse_cfg_file(const char *cfg_filename)fclose (f);sa_sort_arr (); +sp4_sort_arr (); +sp6_sort_arr ();return 0 ;
examples/ipsec-secgw/parser.h +6 -0
@@ -67,10 +67,16 @@ int parse_range(const char *token, uint16_t *low, uint16_t *high);void +sp4_sort_arr (void ); + +void parse_sp4_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status);void +sp6_sort_arr (void ); + +void parse_sp6_tokens (char **tokens,uint32_t n_tokens,struct parse_status *status);
examples/ipsec-secgw/sp4.c +69 -21
150 lines not on this page · raw message
examples/ipsec-secgw/sp6.c +67 -21
148 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v6 6/8 examples/ipsec-secgw: add SAD cache
In reply to Vladimir MedvedkinIntroduce SAD cache.
Stores the most recent SA in a per lcore cache. Cache represents flat array containing SA's indexed by SPI.
--- examples/ipsec-secgw/ipsec-secgw.c | 30 +++++++++- examples/ipsec-secgw/ipsec.h | 1 + examples/ipsec-secgw/sa.c | 32 +---------- examples/ipsec-secgw/sad.c | 40 +++++++++++++ examples/ipsec-secgw/sad.h | 111 ++++++++++++++++++++++++++++++++++--- 5 files changed, 173 insertions(+), 41 deletions(-)
examples/ipsec-secgw/ipsec-secgw.c +27 -3
@@ -46,6 +46,7 @@#include "ipsec.h" #include "parser.h" +#include "sad.h" #define RTE_LOGTYPE_IPSEC RTE_LOGTYPE_USER1
@@ -192,7 +193,10 @@ static uint32_t mtu_size = RTE_ETHER_MTU;static uint64_t frag_ttl_ns =MAX_FRAG_TTL_NS ;/* application wide librte_ipsec/SA parameters */ -struct app_sa_prm app_sa_prm = {.enable =0 }; +struct app_sa_prm app_sa_prm = { + .enable =0 , + .cache_sz =SA_CACHE_SZ + };static const char *cfgfile;struct lcore_rx_queue {
@@ -1102,7 +1106,7 @@ main_loop(__attribute__((unused)) void *dummy)uint16_t portid;uint8_t queueid;struct lcore_conf *qconf; -int32_t socket_id; +int32_t rc, socket_id;const uint64_t drain_tsc = (rte_get_tsc_hz () +US_PER_S -1 ) /US_PER_S *BURST_TX_DRAIN_US ;struct lcore_rx_queue *rxql;
@@ -1132,6 +1136,14 @@ main_loop(__attribute__((unused)) void *dummy) qconf->frag.pool_dir = socket_ctx[socket_id].mbuf_pool; qconf->frag.pool_indir = socket_ctx[socket_id].mbuf_pool_indir; + rc =ipsec_sad_lcore_cache_init (app_sa_prm.cache_sz); +if (rc !=0 ) { +RTE_LOG (ERR ,IPSEC , +"SAD cache init on lcore %u, failed with code: %d\n" , + lcore_id, rc); +return rc; + } +if (qconf->nb_rx_queue ==0 ) {RTE_LOG (DEBUG ,IPSEC ,"lcore %u has nothing to do\n" , lcore_id);
@@ -1271,6 +1283,7 @@ print_usage(const char *prgname)" [-w REPLAY_WINDOW_SIZE]" " [-e]" " [-a]" +" [-c]" " -f CONFIG_FILE" " --config (port,queue,lcore)[,(port,queue,lcore)]" " [--single-sa SAIDX]"
@@ -1290,6 +1303,8 @@ print_usage(const char *prgname)" size for each SA\n" " -e enables ESN\n" " -a enables SA SQN atomic behaviour\n" +" -c specifies inbound SAD cache size,\n" +" zero value disables the cache (default value: 128)\n" " -f CONFIG_FILE: Configuration file\n" " --config (port,queue,lcore): Rx queue configuration\n" " --single-sa SAIDX: Use single SA index for outbound traffic,\n"
@@ -1442,7 +1457,7 @@ parse_args(int32_t argc, char **argv) argvopt = argv; -while ((opt =getopt_long (argc, argvopt,"aelp:Pu:f:j:w:" , +while ((opt =getopt_long (argc, argvopt,"aelp:Pu:f:j:w:c:" , lgopts, &option_index)) !=EOF ) {switch (opt) {
@@ -1501,6 +1516,15 @@ parse_args(int32_t argc, char **argv) app_sa_prm.enable =1 ; app_sa_prm.flags |=RTE_IPSEC_SAFLAG_SQN_ATOM ;break ; +case 'c' : + ret =parse_decimal (optarg); +if (ret <0 ) { +printf ("Invalid SA cache size: %s\n" , optarg); +print_usage (prgname); +return -1 ; + } + app_sa_prm.cache_sz = ret; +break ;case CMD_LINE_OPT_CONFIG_NUM : ret =parse_config (optarg);if (ret) {
examples/ipsec-secgw/ipsec.h +1 -0
@@ -81,6 +81,7 @@ struct app_sa_prm {uint32_t enable;/* use librte_ipsec API for ipsec pkt processing */ uint32_t window_size;/* replay window size */ uint32_t enable_esn;/* enable/disable ESN support */ +uint32_t cache_sz;/* per lcore SA cache size */ uint64_t flags;/* rte_ipsec_sa_prm.flags */ };
examples/ipsec-secgw/sa.c +2 -30
@@ -839,7 +839,7 @@ sa_create(const char *name, int32_t socket_id, uint32_t nb_sa)return NULL ; } - sa_ctx =rte_malloc (NULL ,sizeof (struct sa_ctx ) + + sa_ctx =rte_zmalloc (NULL ,sizeof (struct sa_ctx ) +sizeof (struct ipsec_sa ) * nb_sa,RTE_CACHE_LINE_SIZE );if (sa_ctx ==NULL ) {
@@ -1451,9 +1451,6 @@ inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[], void *sa_arr[], uint16_t nb_pkts) {uint32_t i; -struct ip *ip; -uint32_t *src4_addr; -uint8_t *src6_addr;void *result_sa;struct ipsec_sa *sa;
@@ -1479,32 +1476,7 @@ inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[], intsa |=IPSEC_SA_OFFLOAD_FALLBACK_FLAG ; result_sa = (void *)intsa; } - - ip = rte_pktmbuf_mtod(pkts[i], struct ip *); -switch (WITHOUT_TRANSPORT_VERSION (sa->flags)) { -case IP4_TUNNEL : - src4_addr =RTE_PTR_ADD (ip, - offsetof(struct ip , ip_src)); -if ((ip->ip_v ==IPVERSION ) && - (sa->src.ip.ip4 == *src4_addr) && - (sa->dst.ip.ip4 == *(src4_addr +1 ))) - sa_arr[i] = result_sa; -else - sa_arr[i] =NULL ; -break ; -case IP6_TUNNEL : - src6_addr =RTE_PTR_ADD (ip, - offsetof(struct ip6_hdr , ip6_src)); -if ((ip->ip_v ==IP6_VERSION ) && - !memcmp (&sa->src.ip.ip6.ip6, src6_addr,16 ) && - !memcmp (&sa->dst.ip.ip6.ip6, src6_addr +16 ,16 )) - sa_arr[i] = result_sa; -else - sa_arr[i] =NULL ; -break ; -case TRANSPORT : - sa_arr[i] = result_sa; - } + sa_arr[i] = result_sa; } }
examples/ipsec-secgw/sad.c +40 -0
@@ -3,10 +3,17 @@*/ #include <rte_errno.h> +#include <rte_malloc.h> #include "ipsec.h" #include "sad.h" +RTE_DEFINE_PER_LCORE(struct ipsec_sad_cache, sad_cache) = { + .v4 =NULL , + .v6 =NULL , + .mask =0 , +}; +int ipsec_sad_add (struct ipsec_sad *sad,struct ipsec_sa *sa) {
@@ -65,6 +72,39 @@ ipsec_sad_add(struct ipsec_sad *sad, struct ipsec_sa *sa)return 0 ; } +/* +* Init per lcore SAD cache. +* Must be called by every processing lcore. +*/ +int +ipsec_sad_lcore_cache_init (uint32_t nb_cache_ent) +{ +uint32_t cache_elem; +size_t cache_mem_sz; +struct ipsec_sad_cache *cache; + + cache = &RTE_PER_LCORE (sad_cache); + + cache_elem =rte_align32pow2 (nb_cache_ent); + cache_mem_sz =sizeof (struct ipsec_sa *) * cache_elem; + +if (cache_mem_sz !=0 ) { + cache->v4 =rte_zmalloc_socket (NULL , cache_mem_sz, +RTE_CACHE_LINE_SIZE ,rte_socket_id ()); +if (cache->v4 ==NULL ) +return -rte_errno; + + cache->v6 =rte_zmalloc_socket (NULL , cache_mem_sz, +RTE_CACHE_LINE_SIZE ,rte_socket_id ()); +if (cache->v6 ==NULL ) +return -rte_errno; + + cache->mask = cache_elem -1 ; + } + +return 0 ; +} +int ipsec_sad_create (const char *name,struct ipsec_sad *sad,int socket_id,struct ipsec_sa_cnt *sa_cnt)
examples/ipsec-secgw/sad.h +103 -8
148 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v6 7/8 examples/ipsec-secgw: set/use mbuf ptype
In reply to Vladimir MedvedkinSet mbuf ptype in prepare_one_packet() after parsing ether_type. Use mbuf ptype after to recognize packet's address family.
--- examples/ipsec-secgw/ipsec-secgw.c | 2 ++ examples/ipsec-secgw/sad.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-)
examples/ipsec-secgw/ipsec-secgw.c +2 -0
@@ -323,6 +323,7 @@ prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t) } pkt->l2_len =0 ; pkt->l3_len =sizeof (*iph4); + pkt->packet_type |=RTE_PTYPE_L3_IPV4 ; }else if (eth->ether_type ==rte_cpu_to_be_16 (RTE_ETHER_TYPE_IPV6 )) {int next_proto;size_t l3len, ext_len;
@@ -357,6 +358,7 @@ prepare_one_packet(struct rte_mbuf *pkt, struct ipsec_traffic *t) } pkt->l2_len =0 ; pkt->l3_len = l3len; + pkt->packet_type |=RTE_PTYPE_L3_IPV6 ; }else {/* Unknown/Unsupported type, drop the packet */ RTE_LOG(ERR, IPSEC, "Unsupported packet type 0x%x\n",
examples/ipsec-secgw/sad.h +1 -1
@@ -93,7 +93,7 @@ sad_lookup(struct ipsec_sad *sad, struct rte_mbuf *pkts[], esp = rte_pktmbuf_mtod_offset(pkts[i], struct rte_esp_hdr *, pkts[i]->l3_len); - is_ipv4 = ((ipv4->version_ihl >>4 ) ==IPVERSION ); + is_ipv4 = pkts[i]->packet_type &RTE_PTYPE_L3_IPV4 ; spi =rte_be_to_cpu_32 (esp->spi); cache_idx =SPI2IDX (spi, cache->mask);
Signature · 1 line
2.7.4
PATCH v6 8/8 doc: update ipsec-secgw guide
In reply to Vladimir MedvedkinAdd new SAD cache option in ipsec-secgw guide.
--- doc/guides/sample_app_ug/ipsec_secgw.rst | 6 ++++++ 1 file changed, 6 insertions(+)
doc/guides/sample_app_ug/ipsec_secgw.rst +6 -0
@@ -93,6 +93,7 @@ The application has a number of command line options:: ./build/ipsec-secgw [EAL options] -- -p PORTMASK -P -u PORTMASK -j FRAMESIZE -l -w REPLAY_WINOW_SIZE -e -a + -c SAD_CACHE_SIZE --config (port,queue,lcore)[,(port,queue,lcore] --single-sa SAIDX --rxoffload MASK
@@ -132,6 +133,11 @@ Where: * ``-a``: enables Security Association sequence number atomic behavior (available only with librte_ipsec code path). +* ``-c``: specifies the SAD cache size. Stores the most recent SA in a per + lcore cache. Cache represents flat array containing SA's indexed by SPI. + Zero value disables cache. + Default value: 128. + * ``--config (port,queue,lcore)[,(port,queue,lcore)]``: determines which queues from which ports are mapped to which cores.
Signature · 1 line
2.7.4
Akhil Goyal
AppliedQuoted 54 lines
This series integrates SA database (SAD) capabilities from ipsec library. The goal is to make ipsec-secgw RFC compliant regarding inbound SAD. Also patch series removes hardcoded limitation for maximum number of SA's and SP's.
According to our measurements, after this series of patches, ipsec-secgw performance drops by about 0-2%.v6:
- add SA check for NULL pointer afterrte_ipsec_sad_lookup()
- using mbuf ptype field to distinguish v4 and v6 packets
- add SAD cache size option into documentationv5:
- introduce SAD cache to solve performance degradation
-ipsec_sad_add()returns an error if the key is presentv4:
- put tunnel SA's into SAD withSPI_ONLYtype for performance reasonv3:
- parse SA and SP into sorted array instead of linked listv2:
- get rid of maximum sp limitationVladimir Medvedkin (8):
ipsec: move ipsec sad name length into .h examples/ipsec-secgw: implement inbound SAD examples/ipsec-secgw: integrate inbound SAD examples/ipsec-secgw: get rid of maximum sa limitation examples/ipsec-secgw: get rid of maximum sp limitation examples/ipsec-secgw: add SAD cache examples/ipsec-secgw: set/use mbuf ptype
doc: update ipsec-secgw guidedoc/guides/sample_app_ug/ipsec_secgw.rst | 6 + examples/ipsec-secgw/Makefile | 1 + examples/ipsec-secgw/ipsec-secgw.c | 36 ++++- examples/ipsec-secgw/ipsec.h | 12 +- examples/ipsec-secgw/meson.build | 2 +- examples/ipsec-secgw/parser.c | 4 + examples/ipsec-secgw/parser.h | 9 ++ examples/ipsec-secgw/sa.c | 238 ++++++++++++++++++------------- examples/ipsec-secgw/sad.c | 149 +++++++++++++++++++ examples/ipsec-secgw/sad.h | 170 ++++++++++++++++++++++ examples/ipsec-secgw/sp4.c | 114 +++++++++++---- examples/ipsec-secgw/sp6.c | 112 +++++++++++---- lib/librte_ipsec/ipsec_sad.c | 20 +-- lib/librte_ipsec/rte_ipsec_sad.h | 2 + 14 files changed, 696 insertions(+), 179 deletions(-) create mode 100644 examples/ipsec-secgw/sad.c create mode 100644 examples/ipsec-secgw/sad.h
Quoted 2 lines
--
2.7.4
Squashed the last patch with 6th patch
Applied to dpdk-next-crypto
Thanks.