X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fipsec-secgw%2Fsp4.c;h=3871c6cc10e20b7d4862bd193aab3b80284e1c41;hb=409a346a2e478e8143d150bc72e8bbcbc3ba235b;hp=9c4b256bdbea49d00cc7794b9adb6eba112d5de9;hpb=f159e70b09225d7f4d814dbdaec78f818edc5031;p=dpdk.git diff --git a/examples/ipsec-secgw/sp4.c b/examples/ipsec-secgw/sp4.c index 9c4b256bdb..3871c6cc10 100644 --- a/examples/ipsec-secgw/sp4.c +++ b/examples/ipsec-secgw/sp4.c @@ -1,34 +1,5 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2016 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2016 Intel Corporation */ /* @@ -42,8 +13,21 @@ #include #include "ipsec.h" +#include "parser.h" -#define MAX_ACL_RULE_NUM 1000 +#define MAX_ACL_RULE_NUM 1024 + +#define IPV4_DST_FROM_SP(acr) \ + (rte_cpu_to_be_32((acr).field[DST_FIELD_IPV4].value.u32)) + +#define IPV4_SRC_FROM_SP(acr) \ + (rte_cpu_to_be_32((acr).field[SRC_FIELD_IPV4].value.u32)) + +#define IPV4_DST_MASK_FROM_SP(acr) \ + ((acr).field[DST_FIELD_IPV4].mask_range.u32) + +#define IPV4_SRC_MASK_FROM_SP(acr) \ + ((acr).field[SRC_FIELD_IPV4].mask_range.u32) /* * Rule and trace formats definitions. @@ -72,7 +56,7 @@ enum { RTE_ACL_IPV4_NUM }; -struct rte_acl_field_def ip4_defs[NUM_FIELDS_IPV4] = { +static struct rte_acl_field_def ip4_defs[NUM_FIELDS_IPV4] = { { .type = RTE_ACL_FIELD_TYPE_BITMASK, .size = sizeof(uint8_t), @@ -113,211 +97,311 @@ struct rte_acl_field_def ip4_defs[NUM_FIELDS_IPV4] = { RTE_ACL_RULE_DEF(acl4_rules, RTE_DIM(ip4_defs)); -const struct acl4_rules acl4_rules_out[] = { - { - .data = {.userdata = PROTECT(5), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 105, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(6), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 106, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(10), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 175, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(11), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 176, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(15), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 200, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(16), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 201, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(25), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 55, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(26), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 56, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = BYPASS, .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 240, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = BYPASS, .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 241, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} +static struct acl4_rules acl4_rules_out[MAX_ACL_RULE_NUM]; +static uint32_t nb_acl4_rules_out; + +static struct acl4_rules acl4_rules_in[MAX_ACL_RULE_NUM]; +static uint32_t nb_acl4_rules_in; + +void +parse_sp4_tokens(char **tokens, uint32_t n_tokens, + struct parse_status *status) +{ + struct acl4_rules *rule_ipv4 = NULL; + + uint32_t *ri = NULL; /* rule index */ + uint32_t ti = 0; /* token index */ + uint32_t tv; + + uint32_t esp_p = 0; + uint32_t protect_p = 0; + uint32_t bypass_p = 0; + uint32_t discard_p = 0; + uint32_t pri_p = 0; + uint32_t src_p = 0; + uint32_t dst_p = 0; + uint32_t proto_p = 0; + uint32_t sport_p = 0; + uint32_t dport_p = 0; + + 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]; + + } 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]; + } else { + APP_CHECK(0, status, "unrecognized input \"%s\", expect" + " \"in\" or \"out\"\n", tokens[ti]); + return; } -}; -const struct acl4_rules acl4_rules_in[] = { - { - .data = {.userdata = PROTECT(105), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 115, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(106), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 116, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(110), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 185, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(111), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 186, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(115), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 210, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(116), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 211, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(125), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 65, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = PROTECT(126), .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 66, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = BYPASS, .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 245, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} - }, - { - .data = {.userdata = BYPASS, .category_mask = 1, .priority = 1}, - /* destination IPv4 */ - .field[2] = {.value.u32 = IPv4(192, 168, 246, 0), - .mask_range.u32 = 24,}, - /* source port */ - .field[3] = {.value.u16 = 0, .mask_range.u16 = 0xffff,}, - /* destination port */ - .field[4] = {.value.u16 = 0, .mask_range.u16 = 0xffff,} + rule_ipv4->data.category_mask = 1; + + for (ti = 2; ti < n_tokens; ti++) { + if (strcmp(tokens[ti], "esp") == 0) { + /* currently do nothing */ + APP_CHECK_PRESENCE(esp_p, tokens[ti], status); + if (status->status < 0) + return; + esp_p = 1; + continue; + } + + if (strcmp(tokens[ti], "protect") == 0) { + APP_CHECK_PRESENCE(protect_p, tokens[ti], status); + if (status->status < 0) + return; + APP_CHECK(bypass_p == 0, status, "conflict item " + "between \"%s\" and \"%s\"", tokens[ti], + "bypass"); + if (status->status < 0) + return; + APP_CHECK(discard_p == 0, status, "conflict item " + "between \"%s\" and \"%s\"", tokens[ti], + "discard"); + if (status->status < 0) + return; + INCREMENT_TOKEN_INDEX(ti, n_tokens, status); + if (status->status < 0) + return; + APP_CHECK_TOKEN_IS_NUM(tokens, ti, status); + if (status->status < 0) + return; + + tv = atoi(tokens[ti]); + APP_CHECK(tv != DISCARD && tv != BYPASS, status, + "invalid SPI: %s", tokens[ti]); + if (status->status < 0) + return; + rule_ipv4->data.userdata = tv; + + protect_p = 1; + continue; + } + + if (strcmp(tokens[ti], "bypass") == 0) { + APP_CHECK_PRESENCE(bypass_p, tokens[ti], status); + if (status->status < 0) + return; + APP_CHECK(protect_p == 0, status, "conflict item " + "between \"%s\" and \"%s\"", tokens[ti], + "protect"); + if (status->status < 0) + return; + APP_CHECK(discard_p == 0, status, "conflict item " + "between \"%s\" and \"%s\"", tokens[ti], + "discard"); + if (status->status < 0) + return; + + rule_ipv4->data.userdata = BYPASS; + + bypass_p = 1; + continue; + } + + if (strcmp(tokens[ti], "discard") == 0) { + APP_CHECK_PRESENCE(discard_p, tokens[ti], status); + if (status->status < 0) + return; + APP_CHECK(protect_p == 0, status, "conflict item " + "between \"%s\" and \"%s\"", tokens[ti], + "protect"); + if (status->status < 0) + return; + APP_CHECK(bypass_p == 0, status, "conflict item " + "between \"%s\" and \"%s\"", tokens[ti], + "discard"); + if (status->status < 0) + return; + + rule_ipv4->data.userdata = DISCARD; + + discard_p = 1; + continue; + } + + if (strcmp(tokens[ti], "pri") == 0) { + APP_CHECK_PRESENCE(pri_p, tokens[ti], status); + if (status->status < 0) + return; + INCREMENT_TOKEN_INDEX(ti, n_tokens, status); + if (status->status < 0) + return; + APP_CHECK_TOKEN_IS_NUM(tokens, ti, status); + if (status->status < 0) + return; + + rule_ipv4->data.priority = atoi(tokens[ti]); + + pri_p = 1; + continue; + } + + if (strcmp(tokens[ti], "src") == 0) { + struct in_addr ip; + uint32_t depth; + + APP_CHECK_PRESENCE(src_p, tokens[ti], status); + if (status->status < 0) + return; + INCREMENT_TOKEN_INDEX(ti, n_tokens, status); + if (status->status < 0) + return; + + APP_CHECK(parse_ipv4_addr(tokens[ti], &ip, + &depth) == 0, status, "unrecognized " + "input \"%s\", expect valid ipv4 addr", + tokens[ti]); + if (status->status < 0) + return; + + rule_ipv4->field[1].value.u32 = + rte_bswap32(ip.s_addr); + rule_ipv4->field[1].mask_range.u32 = + depth; + + src_p = 1; + continue; + } + + if (strcmp(tokens[ti], "dst") == 0) { + struct in_addr ip; + uint32_t depth; + + APP_CHECK_PRESENCE(dst_p, tokens[ti], status); + if (status->status < 0) + return; + INCREMENT_TOKEN_INDEX(ti, n_tokens, status); + if (status->status < 0) + return; + APP_CHECK(parse_ipv4_addr(tokens[ti], &ip, + &depth) == 0, status, "unrecognized " + "input \"%s\", expect valid ipv4 addr", + tokens[ti]); + if (status->status < 0) + return; + + rule_ipv4->field[2].value.u32 = + rte_bswap32(ip.s_addr); + rule_ipv4->field[2].mask_range.u32 = + depth; + + dst_p = 1; + continue; + } + + if (strcmp(tokens[ti], "proto") == 0) { + uint16_t low, high; + + APP_CHECK_PRESENCE(proto_p, tokens[ti], status); + if (status->status < 0) + return; + INCREMENT_TOKEN_INDEX(ti, n_tokens, status); + if (status->status < 0) + return; + + APP_CHECK(parse_range(tokens[ti], &low, &high) + == 0, status, "unrecognized input \"%s\"" + ", expect \"from:to\"", tokens[ti]); + if (status->status < 0) + return; + APP_CHECK(low <= 0xff, status, "proto low " + "over-limit"); + if (status->status < 0) + return; + APP_CHECK(high <= 0xff, status, "proto high " + "over-limit"); + if (status->status < 0) + return; + + rule_ipv4->field[0].value.u8 = (uint8_t)low; + rule_ipv4->field[0].mask_range.u8 = (uint8_t)high; + + proto_p = 1; + continue; + } + + if (strcmp(tokens[ti], "sport") == 0) { + uint16_t port_low, port_high; + + APP_CHECK_PRESENCE(sport_p, tokens[ti], status); + if (status->status < 0) + return; + INCREMENT_TOKEN_INDEX(ti, n_tokens, status); + if (status->status < 0) + return; + + APP_CHECK(parse_range(tokens[ti], &port_low, + &port_high) == 0, status, "unrecognized " + "input \"%s\", expect \"port_from:" + "port_to\"", tokens[ti]); + if (status->status < 0) + return; + + rule_ipv4->field[3].value.u16 = port_low; + rule_ipv4->field[3].mask_range.u16 = port_high; + + sport_p = 1; + continue; + } + + if (strcmp(tokens[ti], "dport") == 0) { + uint16_t port_low, port_high; + + APP_CHECK_PRESENCE(dport_p, tokens[ti], status); + if (status->status < 0) + return; + INCREMENT_TOKEN_INDEX(ti, n_tokens, status); + if (status->status < 0) + return; + + APP_CHECK(parse_range(tokens[ti], &port_low, + &port_high) == 0, status, "unrecognized " + "input \"%s\", expect \"port_from:" + "port_to\"", tokens[ti]); + if (status->status < 0) + return; + + rule_ipv4->field[4].value.u16 = port_low; + rule_ipv4->field[4].mask_range.u16 = port_high; + + dport_p = 1; + continue; + } + + /* unrecognizeable input */ + APP_CHECK(0, status, "unrecognized input \"%s\"", + tokens[ti]); + return; } -}; + + /* check if argument(s) are missing */ + APP_CHECK(esp_p == 1, status, "missing argument \"esp\""); + if (status->status < 0) + return; + + APP_CHECK(protect_p | bypass_p | discard_p, status, "missing " + "argument \"protect\", \"bypass\", or \"discard\""); + if (status->status < 0) + return; + + *ri = *ri + 1; +} static void print_one_ip4_rule(const struct acl4_rules *rule, int32_t extra) @@ -405,12 +489,40 @@ acl4_init(const char *name, int32_t socketid, const struct acl4_rules *rules, return ctx; } +/* + * check that for each rule it's SPI has a correspondent entry in SAD + */ +static int +check_spi_value(int inbound) +{ + uint32_t i, num, spi; + const struct acl4_rules *acr; + + if (inbound != 0) { + acr = acl4_rules_in; + num = nb_acl4_rules_in; + } else { + acr = acl4_rules_out; + num = nb_acl4_rules_out; + } + + 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; + } + } + + return 0; +} + void -sp4_init(struct socket_ctx *ctx, int32_t socket_id, uint32_t ep) +sp4_init(struct socket_ctx *ctx, int32_t socket_id) { const char *name; - const struct acl4_rules *rules_out, *rules_in; - uint32_t nb_out_rules, nb_in_rules; if (ctx == NULL) rte_exit(EXIT_FAILURE, "NULL context.\n"); @@ -423,25 +535,60 @@ sp4_init(struct socket_ctx *ctx, int32_t socket_id, uint32_t ep) rte_exit(EXIT_FAILURE, "Outbound SP DB for socket %u already " "initialized\n", socket_id); - if (ep == 0) { - rules_out = acl4_rules_out; - nb_out_rules = RTE_DIM(acl4_rules_out); - rules_in = acl4_rules_in; - nb_in_rules = RTE_DIM(acl4_rules_in); - } else if (ep == 1) { - rules_out = acl4_rules_in; - nb_out_rules = RTE_DIM(acl4_rules_in); - rules_in = acl4_rules_out; - nb_in_rules = RTE_DIM(acl4_rules_out); + if (check_spi_value(1) < 0) + rte_exit(EXIT_FAILURE, + "Inbound IPv4 SP DB has unmatched in SAD SPIs\n"); + + if (check_spi_value(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); } else - rte_exit(EXIT_FAILURE, "Invalid EP value %u. " - "Only 0 or 1 supported.\n", ep); + RTE_LOG(WARNING, IPSEC, "No IPv4 SP Inbound rule " + "specified\n"); - name = "sp_ip4_in"; - ctx->sp_ip4_in = (struct sp_ctx *)acl4_init(name, socket_id, - rules_in, nb_in_rules); + 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); + } else + RTE_LOG(WARNING, IPSEC, "No IPv4 SP Outbound rule " + "specified\n"); +} + +/* + * Search though SP rules for given SPI. + */ +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; + + if (inbound != 0) { + acr = acl4_rules_in; + num = nb_acl4_rules_in; + } else { + acr = acl4_rules_out; + 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; + } + } - name = "sp_ip4_out"; - ctx->sp_ip4_out = (struct sp_ctx *)acl4_init(name, socket_id, - rules_out, nb_out_rules); + return -ENOENT; }