X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fipsec-secgw%2Fsp6.c;h=d8be6b1bd23c624390457c045207153884f5f324;hb=089e5ed727a15da2729cfee9b63533dd120bd04c;hp=dc5b94c6a9cd93fe405c6030a10163dcdcdbe823;hpb=d92fc70e14f43d13be4204c51ed7f3a671c1bcc4;p=dpdk.git diff --git a/examples/ipsec-secgw/sp6.c b/examples/ipsec-secgw/sp6.c index dc5b94c6a9..d8be6b1bd2 100644 --- a/examples/ipsec-secgw/sp6.c +++ b/examples/ipsec-secgw/sp6.c @@ -17,6 +17,36 @@ #define MAX_ACL_RULE_NUM 1024 +#define IPV6_FROM_SP(acr, fidx_low, fidx_high) \ + (((uint64_t)(acr).field[(fidx_high)].value.u32 << 32) | \ + (acr).field[(fidx_low)].value.u32) + +#define IPV6_DST_FROM_SP(addr, acr) do {\ + (addr).ip.ip6.ip6[0] = rte_cpu_to_be_64(IPV6_FROM_SP((acr), \ + IP6_DST1, IP6_DST0));\ + (addr).ip.ip6.ip6[1] = rte_cpu_to_be_64(IPV6_FROM_SP((acr), \ + IP6_DST3, IP6_DST2));\ + } while (0) + +#define IPV6_SRC_FROM_SP(addr, acr) do {\ + (addr).ip.ip6.ip6[0] = rte_cpu_to_be_64(IPV6_FROM_SP((acr), \ + IP6_SRC1, IP6_SRC0));\ + (addr).ip.ip6.ip6[1] = rte_cpu_to_be_64(IPV6_FROM_SP((acr), \ + IP6_SRC3, IP6_SRC2));\ + } while (0) + +#define IPV6_DST_MASK_FROM_SP(mask, acr) \ + ((mask) = (acr).field[IP6_DST0].mask_range.u32 + \ + (acr).field[IP6_DST1].mask_range.u32 + \ + (acr).field[IP6_DST2].mask_range.u32 + \ + (acr).field[IP6_DST3].mask_range.u32) + +#define IPV6_SRC_MASK_FROM_SP(mask, acr) \ + ((mask) = (acr).field[IP6_SRC0].mask_range.u32 + \ + (acr).field[IP6_SRC1].mask_range.u32 + \ + (acr).field[IP6_SRC2].mask_range.u32 + \ + (acr).field[IP6_SRC3].mask_range.u32) + enum { IP6_PROTO, IP6_SRC0, @@ -130,6 +160,7 @@ parse_sp6_tokens(char **tokens, uint32_t n_tokens, 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; @@ -202,8 +233,12 @@ parse_sp6_tokens(char **tokens, uint32_t n_tokens, if (status->status < 0) return; - rule_ipv6->data.userdata = - PROTECT(atoi(tokens[ti])); + tv = atoi(tokens[ti]); + APP_CHECK(tv != DISCARD && tv != BYPASS, status, + "invalid SPI: %s", tokens[ti]); + if (status->status < 0) + return; + rule_ipv6->data.userdata = tv; protect_p = 1; continue; @@ -586,6 +621,36 @@ acl6_init(const char *name, int32_t socketid, const struct acl6_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 acl6_rules *acr; + + if (inbound != 0) { + acr = acl6_rules_in; + num = nb_acl6_rules_in; + } else { + acr = acl6_rules_out; + num = nb_acl6_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 sp6_init(struct socket_ctx *ctx, int32_t socket_id) { @@ -602,6 +667,14 @@ 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) + rte_exit(EXIT_FAILURE, + "Inbound IPv6 SP DB has unmatched in SAD SPIs\n"); + + if (check_spi_value(0) < 0) + rte_exit(EXIT_FAILURE, + "Outbound IPv6 SP DB has unmatched in SAD SPIs\n"); + if (nb_acl6_rules_in > 0) { name = "sp_ip6_in"; ctx->sp_ip6_in = (struct sp_ctx *)acl6_init(name, @@ -618,3 +691,36 @@ sp6_init(struct socket_ctx *ctx, int32_t socket_id) RTE_LOG(WARNING, IPSEC, "No IPv6 SP Outbound rule " "specified\n"); } + +/* + * Search though SP rules for given SPI. + */ +int +sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2], + uint32_t mask[2]) +{ + uint32_t i, num; + const struct acl6_rules *acr; + + if (inbound != 0) { + acr = acl6_rules_in; + num = nb_acl6_rules_in; + } else { + acr = acl6_rules_out; + 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; + } + } + + return -ENOENT; +}