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:
parent
e1143d7dbb
commit
b0806375ae
@ -643,6 +643,8 @@ parse_cfg_file(const char *cfg_filename)
|
||||
fclose(f);
|
||||
|
||||
sa_sort_arr();
|
||||
sp4_sort_arr();
|
||||
sp6_sort_arr();
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user