examples/ipsec-secgw: get rid of maximum SP limitation

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 <vladimir.medvedkin@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
Acked-by: Anoob Joseph <anoobj@marvell.com>
This commit is contained in:
Vladimir Medvedkin 2020-01-31 17:39:42 +00:00 committed by Akhil Goyal
parent e1143d7dbb
commit b0806375ae
4 changed files with 144 additions and 42 deletions

View File

@ -643,6 +643,8 @@ parse_cfg_file(const char *cfg_filename)
fclose(f);
sa_sort_arr();
sp4_sort_arr();
sp6_sort_arr();
return 0;

View File

@ -66,10 +66,16 @@ parse_ipv6_addr(const char *token, struct in6_addr *ipv6, uint32_t *mask);
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);

View File

@ -15,7 +15,7 @@
#include "ipsec.h"
#include "parser.h"
#define MAX_ACL_RULE_NUM 1024
#define INIT_ACL_RULE_NUM 128
#define IPV4_DST_FROM_SP(acr) \
(rte_cpu_to_be_32((acr).field[DST_FIELD_IPV4].value.u32))
@ -97,11 +97,39 @@ 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];
static struct acl4_rules *acl4_rules_out;
static uint32_t nb_acl4_rules_out;
static uint32_t sp_out_sz;
static struct acl4_rules acl4_rules_in[MAX_ACL_RULE_NUM];
static struct acl4_rules *acl4_rules_in;
static uint32_t nb_acl4_rules_in;
static uint32_t sp_in_sz;
static int
extend_sp_arr(struct acl4_rules **sp_tbl, uint32_t cur_cnt, uint32_t *cur_sz)
{
if (*sp_tbl == NULL) {
*sp_tbl = calloc(INIT_ACL_RULE_NUM, sizeof(struct acl4_rules));
if (*sp_tbl == NULL)
return -1;
*cur_sz = INIT_ACL_RULE_NUM;
return 0;
}
if (cur_cnt >= *cur_sz) {
*sp_tbl = realloc(*sp_tbl,
*cur_sz * sizeof(struct acl4_rules) * 2);
if (*sp_tbl == NULL)
return -1;
/* clean reallocated extra space */
memset(&(*sp_tbl)[*cur_sz], 0,
*cur_sz * sizeof(struct acl4_rules));
*cur_sz *= 2;
}
return 0;
}
void
parse_sp4_tokens(char **tokens, uint32_t n_tokens,
@ -127,9 +155,8 @@ parse_sp4_tokens(char **tokens, uint32_t n_tokens,
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)
if (extend_sp_arr(&acl4_rules_in, nb_acl4_rules_in,
&sp_in_sz) < 0)
return;
rule_ipv4 = &acl4_rules_in[*ri];
@ -137,9 +164,8 @@ parse_sp4_tokens(char **tokens, uint32_t n_tokens,
} 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)
if (extend_sp_arr(&acl4_rules_out, nb_acl4_rules_out,
&sp_out_sz) < 0)
return;
rule_ipv4 = &acl4_rules_out[*ri];
@ -451,7 +477,7 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules,
struct rte_acl_config acl_build_param;
struct rte_acl_ctx *ctx;
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));
@ -464,7 +490,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)
@ -566,6 +592,16 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id)
"specified\n");
}
static int
sp_cmp(const void *p, const void *q)
{
uint32_t spi1 = ((const struct acl4_rules *)p)->data.userdata;
uint32_t spi2 = ((const struct acl4_rules *)q)->data.userdata;
return (int)(spi1 - spi2);
}
/*
* Search though SP rules for given SPI.
*/
@ -573,8 +609,10 @@ int
sp4_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],
uint32_t mask[2])
{
uint32_t i, num;
uint32_t num;
struct acl4_rules *rule;
const struct acl4_rules *acr;
struct acl4_rules tmpl;
if (inbound != 0) {
acr = acl4_rules_in;
@ -584,17 +622,27 @@ sp4_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],
num = nb_acl4_rules_out;
}
for (i = 0; i != num; i++) {
if (acr[i].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]);
}
return i;
tmpl.data.userdata = spi;
rule = bsearch(&tmpl, acr, num, sizeof(struct acl4_rules), sp_cmp);
if (rule != NULL) {
if (NULL != ip_addr && NULL != mask) {
ip_addr[0].ip.ip4 = IPV4_SRC_FROM_SP(*rule);
ip_addr[1].ip.ip4 = IPV4_DST_FROM_SP(*rule);
mask[0] = IPV4_SRC_MASK_FROM_SP(*rule);
mask[1] = IPV4_DST_MASK_FROM_SP(*rule);
}
return RTE_PTR_DIFF(rule, acr) / sizeof(struct acl4_rules);
}
return -ENOENT;
}
void
sp4_sort_arr(void)
{
qsort(acl4_rules_in, nb_acl4_rules_in, sizeof(struct acl4_rules),
sp_cmp);
qsort(acl4_rules_out, nb_acl4_rules_out, sizeof(struct acl4_rules),
sp_cmp);
}

View File

@ -15,7 +15,7 @@
#include "ipsec.h"
#include "parser.h"
#define MAX_ACL_RULE_NUM 1024
#define INIT_ACL_RULE_NUM 128
#define IPV6_FROM_SP(acr, fidx_low, fidx_high) \
(((uint64_t)(acr).field[(fidx_high)].value.u32 << 32) | \
@ -146,11 +146,38 @@ static struct rte_acl_field_def ip6_defs[IP6_NUM] = {
RTE_ACL_RULE_DEF(acl6_rules, RTE_DIM(ip6_defs));
static struct acl6_rules acl6_rules_out[MAX_ACL_RULE_NUM];
static struct acl6_rules *acl6_rules_out;
static uint32_t nb_acl6_rules_out;
static uint32_t sp_out_sz;
static struct acl6_rules acl6_rules_in[MAX_ACL_RULE_NUM];
static struct acl6_rules *acl6_rules_in;
static uint32_t nb_acl6_rules_in;
static uint32_t sp_in_sz;
static int
extend_sp_arr(struct acl6_rules **sp_tbl, uint32_t cur_cnt, uint32_t *cur_sz)
{
if (*sp_tbl == NULL) {
*sp_tbl = calloc(INIT_ACL_RULE_NUM, sizeof(struct acl6_rules));
if (*sp_tbl == NULL)
return -1;
*cur_sz = INIT_ACL_RULE_NUM;
return 0;
}
if (cur_cnt >= *cur_sz) {
*sp_tbl = realloc(*sp_tbl,
*cur_sz * sizeof(struct acl6_rules) * 2);
if (*sp_tbl == NULL)
return -1;
/* clean reallocated extra space */
memset(&(*sp_tbl)[*cur_sz], 0,
*cur_sz * sizeof(struct acl6_rules));
*cur_sz *= 2;
}
return 0;
}
void
parse_sp6_tokens(char **tokens, uint32_t n_tokens,
@ -176,9 +203,8 @@ parse_sp6_tokens(char **tokens, uint32_t n_tokens,
if (strcmp(tokens[1], "in") == 0) {
ri = &nb_acl6_rules_in;
APP_CHECK(*ri <= MAX_ACL_RULE_NUM - 1, status, "too "
"many sp rules, abort insertion\n");
if (status->status < 0)
if (extend_sp_arr(&acl6_rules_in, nb_acl6_rules_in,
&sp_in_sz) < 0)
return;
rule_ipv6 = &acl6_rules_in[*ri];
@ -186,9 +212,8 @@ parse_sp6_tokens(char **tokens, uint32_t n_tokens,
} else if (strcmp(tokens[1], "out") == 0) {
ri = &nb_acl6_rules_out;
APP_CHECK(*ri <= MAX_ACL_RULE_NUM - 1, status, "too "
"many sp rules, abort insertion\n");
if (status->status < 0)
if (extend_sp_arr(&acl6_rules_out, nb_acl6_rules_out,
&sp_out_sz) < 0)
return;
rule_ipv6 = &acl6_rules_out[*ri];
@ -583,7 +608,7 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_rules *rules,
struct rte_acl_config acl_build_param;
struct rte_acl_ctx *ctx;
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));
@ -596,7 +621,7 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_rules *rules,
acl_param.name = s;
acl_param.socket_id = socketid;
acl_param.rule_size = RTE_ACL_RULE_SZ(RTE_DIM(ip6_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)
@ -698,6 +723,15 @@ sp6_init(struct socket_ctx *ctx, int32_t socket_id)
"specified\n");
}
static int
sp_cmp(const void *p, const void *q)
{
uint32_t spi1 = ((const struct acl6_rules *)p)->data.userdata;
uint32_t spi2 = ((const struct acl6_rules *)q)->data.userdata;
return (int)(spi1 - spi2);
}
/*
* Search though SP rules for given SPI.
*/
@ -705,8 +739,10 @@ int
sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],
uint32_t mask[2])
{
uint32_t i, num;
uint32_t num;
struct acl6_rules *rule;
const struct acl6_rules *acr;
struct acl6_rules tmpl;
if (inbound != 0) {
acr = acl6_rules_in;
@ -716,17 +752,27 @@ sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],
num = nb_acl6_rules_out;
}
for (i = 0; i != num; i++) {
if (acr[i].data.userdata == spi) {
if (NULL != ip_addr && NULL != mask) {
IPV6_SRC_FROM_SP(ip_addr[0], acr[i]);
IPV6_DST_FROM_SP(ip_addr[1], acr[i]);
IPV6_SRC_MASK_FROM_SP(mask[0], acr[i]);
IPV6_DST_MASK_FROM_SP(mask[1], acr[i]);
}
return i;
tmpl.data.userdata = spi;
rule = bsearch(&tmpl, acr, num, sizeof(struct acl6_rules), sp_cmp);
if (rule != NULL) {
if (NULL != ip_addr && NULL != mask) {
IPV6_SRC_FROM_SP(ip_addr[0], *rule);
IPV6_DST_FROM_SP(ip_addr[1], *rule);
IPV6_SRC_MASK_FROM_SP(mask[0], *rule);
IPV6_DST_MASK_FROM_SP(mask[1], *rule);
}
return RTE_PTR_DIFF(rule, acr) / sizeof(struct acl6_rules);
}
return -ENOENT;
}
void
sp6_sort_arr(void)
{
qsort(acl6_rules_in, nb_acl6_rules_in, sizeof(struct acl6_rules),
sp_cmp);
qsort(acl6_rules_out, nb_acl6_rules_out, sizeof(struct acl6_rules),
sp_cmp);
}