X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fipsec-secgw%2Fsa.c;h=ab18b81103196157237089bd7a4eccd352ae53d6;hb=99c12dcca65d;hp=a5b8a632fd7f9a0cf927daac28bed5c09bc3a063;hpb=55d4c7756c5dd6fedc6327d08fae153a18d0f5a6;p=dpdk.git diff --git a/examples/ipsec-secgw/sa.c b/examples/ipsec-secgw/sa.c index a5b8a632fd..ab18b81103 100644 --- a/examples/ipsec-secgw/sa.c +++ b/examples/ipsec-secgw/sa.c @@ -37,170 +37,200 @@ #include #include #include +#include #include #include #include #include #include +#include #include "ipsec.h" #include "esp.h" -/* SAs EP0 Outbound */ -const struct ipsec_sa sa_ep0_out[] = { - { 5, 0, IPv4(172, 16, 1, 5), IPv4(172, 16, 2, 5), - NULL, NULL, - esp4_tunnel_outbound_pre_crypto, - esp4_tunnel_outbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 6, 0, IPv4(172, 16, 1, 6), IPv4(172, 16, 2, 6), - NULL, NULL, - esp4_tunnel_outbound_pre_crypto, - esp4_tunnel_outbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 7, 0, IPv4(172, 16, 1, 7), IPv4(172, 16, 2, 7), - NULL, NULL, - esp4_tunnel_outbound_pre_crypto, - esp4_tunnel_outbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 8, 0, IPv4(172, 16, 1, 8), IPv4(172, 16, 2, 8), - NULL, NULL, - esp4_tunnel_outbound_pre_crypto, - esp4_tunnel_outbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 9, 0, IPv4(172, 16, 1, 5), IPv4(172, 16, 2, 5), - NULL, NULL, - esp4_tunnel_outbound_pre_crypto, - esp4_tunnel_outbound_post_crypto, - RTE_CRYPTO_CIPHER_NULL, RTE_CRYPTO_AUTH_NULL, - 0, 0, 4, - 0, 0 }, +/* SAs Outbound */ +const struct ipsec_sa sa_out[] = { + { + .spi = 5, + .src.ip4 = IPv4(172, 16, 1, 5), + .dst.ip4 = IPv4(172, 16, 2, 5), + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .digest_len = 12, + .iv_len = 16, + .block_size = 16, + .flags = IP4_TUNNEL + }, + { + .spi = 6, + .src.ip4 = IPv4(172, 16, 1, 6), + .dst.ip4 = IPv4(172, 16, 2, 6), + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .digest_len = 12, + .iv_len = 16, + .block_size = 16, + .flags = IP4_TUNNEL + }, + { + .spi = 10, + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .digest_len = 12, + .iv_len = 16, + .block_size = 16, + .flags = TRANSPORT + }, + { + .spi = 11, + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .digest_len = 12, + .iv_len = 16, + .block_size = 16, + .flags = TRANSPORT + }, + { + .spi = 15, + .src.ip4 = IPv4(172, 16, 1, 5), + .dst.ip4 = IPv4(172, 16, 2, 5), + .cipher_algo = RTE_CRYPTO_CIPHER_NULL, + .auth_algo = RTE_CRYPTO_AUTH_NULL, + .digest_len = 0, + .iv_len = 0, + .block_size = 4, + .flags = IP4_TUNNEL + }, + { + .spi = 16, + .src.ip4 = IPv4(172, 16, 1, 6), + .dst.ip4 = IPv4(172, 16, 2, 6), + .cipher_algo = RTE_CRYPTO_CIPHER_NULL, + .auth_algo = RTE_CRYPTO_AUTH_NULL, + .digest_len = 0, + .iv_len = 0, + .block_size = 4, + .flags = IP4_TUNNEL + }, + { + .spi = 25, + .src.ip6_b = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x55, 0x55 }, + .dst.ip6_b = { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x55, 0x55 }, + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .digest_len = 12, + .iv_len = 16, + .block_size = 16, + .flags = IP6_TUNNEL + }, + { + .spi = 26, + .src.ip6_b = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x66, 0x66 }, + .dst.ip6_b = { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x66, 0x66 }, + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .digest_len = 12, + .iv_len = 16, + .block_size = 16, + .flags = IP6_TUNNEL + }, }; -/* SAs EP0 Inbound */ -const struct ipsec_sa sa_ep0_in[] = { - { 5, 0, IPv4(172, 16, 2, 5), IPv4(172, 16, 1, 5), - NULL, NULL, - esp4_tunnel_inbound_pre_crypto, - esp4_tunnel_inbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 6, 0, IPv4(172, 16, 2, 6), IPv4(172, 16, 1, 6), - NULL, NULL, - esp4_tunnel_inbound_pre_crypto, - esp4_tunnel_inbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 7, 0, IPv4(172, 16, 2, 7), IPv4(172, 16, 1, 7), - NULL, NULL, - esp4_tunnel_inbound_pre_crypto, - esp4_tunnel_inbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 8, 0, IPv4(172, 16, 2, 8), IPv4(172, 16, 1, 8), - NULL, NULL, - esp4_tunnel_inbound_pre_crypto, - esp4_tunnel_inbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 9, 0, IPv4(172, 16, 2, 5), IPv4(172, 16, 1, 5), - NULL, NULL, - esp4_tunnel_inbound_pre_crypto, - esp4_tunnel_inbound_post_crypto, - RTE_CRYPTO_CIPHER_NULL, RTE_CRYPTO_AUTH_NULL, - 0, 0, 4, - 0, 0 }, -}; - -/* SAs EP1 Outbound */ -const struct ipsec_sa sa_ep1_out[] = { - { 5, 0, IPv4(172, 16, 2, 5), IPv4(172, 16, 1, 5), - NULL, NULL, - esp4_tunnel_outbound_pre_crypto, - esp4_tunnel_outbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 6, 0, IPv4(172, 16, 2, 6), IPv4(172, 16, 1, 6), - NULL, NULL, - esp4_tunnel_outbound_pre_crypto, - esp4_tunnel_outbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 7, 0, IPv4(172, 16, 2, 7), IPv4(172, 16, 1, 7), - NULL, NULL, - esp4_tunnel_outbound_pre_crypto, - esp4_tunnel_outbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 8, 0, IPv4(172, 16, 2, 8), IPv4(172, 16, 1, 8), - NULL, NULL, - esp4_tunnel_outbound_pre_crypto, - esp4_tunnel_outbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 9, 0, IPv4(172, 16, 2, 5), IPv4(172, 16, 1, 5), - NULL, NULL, - esp4_tunnel_outbound_pre_crypto, - esp4_tunnel_outbound_post_crypto, - RTE_CRYPTO_CIPHER_NULL, RTE_CRYPTO_AUTH_NULL, - 0, 0, 4, - 0, 0 }, -}; - -/* SAs EP1 Inbound */ -const struct ipsec_sa sa_ep1_in[] = { - { 5, 0, IPv4(172, 16, 1, 5), IPv4(172, 16, 2, 5), - NULL, NULL, - esp4_tunnel_inbound_pre_crypto, - esp4_tunnel_inbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 6, 0, IPv4(172, 16, 1, 6), IPv4(172, 16, 2, 6), - NULL, NULL, - esp4_tunnel_inbound_pre_crypto, - esp4_tunnel_inbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 7, 0, IPv4(172, 16, 1, 7), IPv4(172, 16, 2, 7), - NULL, NULL, - esp4_tunnel_inbound_pre_crypto, - esp4_tunnel_inbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 8, 0, IPv4(172, 16, 1, 8), IPv4(172, 16, 2, 8), - NULL, NULL, - esp4_tunnel_inbound_pre_crypto, - esp4_tunnel_inbound_post_crypto, - RTE_CRYPTO_CIPHER_AES_CBC, RTE_CRYPTO_AUTH_SHA1_HMAC, - 12, 16, 16, - 0, 0 }, - { 9, 0, IPv4(172, 16, 1, 5), IPv4(172, 16, 2, 5), - NULL, NULL, - esp4_tunnel_inbound_pre_crypto, - esp4_tunnel_inbound_post_crypto, - RTE_CRYPTO_CIPHER_NULL, RTE_CRYPTO_AUTH_NULL, - 0, 0, 4, - 0, 0 }, +/* SAs Inbound */ +const struct ipsec_sa sa_in[] = { + { + .spi = 105, + .src.ip4 = IPv4(172, 16, 2, 5), + .dst.ip4 = IPv4(172, 16, 1, 5), + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .digest_len = 12, + .iv_len = 16, + .block_size = 16, + .flags = IP4_TUNNEL + }, + { + .spi = 106, + .src.ip4 = IPv4(172, 16, 2, 6), + .dst.ip4 = IPv4(172, 16, 1, 6), + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .digest_len = 12, + .iv_len = 16, + .block_size = 16, + .flags = IP4_TUNNEL + }, + { + .spi = 110, + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .digest_len = 12, + .iv_len = 16, + .block_size = 16, + .flags = TRANSPORT + }, + { + .spi = 111, + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .digest_len = 12, + .iv_len = 16, + .block_size = 16, + .flags = TRANSPORT + }, + { + .spi = 115, + .src.ip4 = IPv4(172, 16, 2, 5), + .dst.ip4 = IPv4(172, 16, 1, 5), + .cipher_algo = RTE_CRYPTO_CIPHER_NULL, + .auth_algo = RTE_CRYPTO_AUTH_NULL, + .digest_len = 0, + .iv_len = 0, + .block_size = 4, + .flags = IP4_TUNNEL + }, + { + .spi = 116, + .src.ip4 = IPv4(172, 16, 2, 6), + .dst.ip4 = IPv4(172, 16, 1, 6), + .cipher_algo = RTE_CRYPTO_CIPHER_NULL, + .auth_algo = RTE_CRYPTO_AUTH_NULL, + .digest_len = 0, + .iv_len = 0, + .block_size = 4, + .flags = IP4_TUNNEL + }, + { + .spi = 125, + .src.ip6_b = { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x55, 0x55 }, + .dst.ip6_b = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x55, 0x55 }, + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .digest_len = 12, + .iv_len = 16, + .block_size = 16, + .flags = IP6_TUNNEL + }, + { + .spi = 126, + .src.ip6_b = { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x66, 0x66 }, + .dst.ip6_b = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x66, 0x66 }, + .cipher_algo = RTE_CRYPTO_CIPHER_AES_CBC, + .auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC, + .digest_len = 12, + .iv_len = 16, + .block_size = 16, + .flags = IP6_TUNNEL + }, }; static uint8_t cipher_key[256] = "sixteenbytes key"; @@ -209,15 +239,17 @@ static uint8_t cipher_key[256] = "sixteenbytes key"; const struct rte_crypto_sym_xform aescbc_enc_xf = { NULL, RTE_CRYPTO_SYM_XFORM_CIPHER, - .cipher = { RTE_CRYPTO_CIPHER_OP_ENCRYPT, RTE_CRYPTO_CIPHER_AES_CBC, + {.cipher = { RTE_CRYPTO_CIPHER_OP_ENCRYPT, RTE_CRYPTO_CIPHER_AES_CBC, .key = { cipher_key, 16 } } + } }; const struct rte_crypto_sym_xform aescbc_dec_xf = { NULL, RTE_CRYPTO_SYM_XFORM_CIPHER, - .cipher = { RTE_CRYPTO_CIPHER_OP_DECRYPT, RTE_CRYPTO_CIPHER_AES_CBC, + {.cipher = { RTE_CRYPTO_CIPHER_OP_DECRYPT, RTE_CRYPTO_CIPHER_AES_CBC, .key = { cipher_key, 16 } } + } }; static uint8_t auth_key[256] = "twentybytes hash key"; @@ -226,28 +258,32 @@ static uint8_t auth_key[256] = "twentybytes hash key"; const struct rte_crypto_sym_xform sha1hmac_gen_xf = { NULL, RTE_CRYPTO_SYM_XFORM_AUTH, - .auth = { RTE_CRYPTO_AUTH_OP_GENERATE, RTE_CRYPTO_AUTH_SHA1_HMAC, + {.auth = { RTE_CRYPTO_AUTH_OP_GENERATE, RTE_CRYPTO_AUTH_SHA1_HMAC, .key = { auth_key, 20 }, 12, 0 } + } }; const struct rte_crypto_sym_xform sha1hmac_verify_xf = { NULL, RTE_CRYPTO_SYM_XFORM_AUTH, - .auth = { RTE_CRYPTO_AUTH_OP_VERIFY, RTE_CRYPTO_AUTH_SHA1_HMAC, + {.auth = { RTE_CRYPTO_AUTH_OP_VERIFY, RTE_CRYPTO_AUTH_SHA1_HMAC, .key = { auth_key, 20 }, 12, 0 } + } }; /* AES CBC xform */ const struct rte_crypto_sym_xform null_cipher_xf = { NULL, RTE_CRYPTO_SYM_XFORM_CIPHER, - .cipher = { .algo = RTE_CRYPTO_CIPHER_NULL } + {.cipher = { .algo = RTE_CRYPTO_CIPHER_NULL } + } }; const struct rte_crypto_sym_xform null_auth_xf = { NULL, RTE_CRYPTO_SYM_XFORM_AUTH, - .auth = { .algo = RTE_CRYPTO_AUTH_NULL } + {.auth = { .algo = RTE_CRYPTO_AUTH_NULL } + } }; struct sa_ctx { @@ -259,11 +295,11 @@ struct sa_ctx { }; static struct sa_ctx * -sa_ipv4_create(const char *name, int socket_id) +sa_create(const char *name, int32_t socket_id) { char s[PATH_MAX]; struct sa_ctx *sa_ctx; - unsigned mz_size; + uint32_t mz_size; const struct rte_memzone *mz; snprintf(s, sizeof(s), "%s_%u", name, socket_id); @@ -288,10 +324,10 @@ sa_ipv4_create(const char *name, int socket_id) static int sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], - unsigned nb_entries, unsigned inbound) + uint32_t nb_entries, uint32_t inbound) { struct ipsec_sa *sa; - unsigned i, idx; + uint32_t i, idx; for (i = 0; i < nb_entries; i++) { idx = SPI2IDX(entries[i].spi); @@ -302,8 +338,14 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], return -EINVAL; } *sa = entries[i]; - sa->src = rte_cpu_to_be_32(sa->src); - sa->dst = rte_cpu_to_be_32(sa->dst); + sa->seq = 0; + + switch (sa->flags) { + case IP4_TUNNEL: + sa->src.ip4 = rte_cpu_to_be_32(sa->src.ip4); + sa->dst.ip4 = rte_cpu_to_be_32(sa->dst.ip4); + } + if (inbound) { if (sa->cipher_algo == RTE_CRYPTO_CIPHER_NULL) { sa_ctx->xf[idx].a = null_auth_xf; @@ -331,65 +373,65 @@ sa_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], static inline int sa_out_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], - unsigned nb_entries) + uint32_t nb_entries) { return sa_add_rules(sa_ctx, entries, nb_entries, 0); } static inline int sa_in_add_rules(struct sa_ctx *sa_ctx, const struct ipsec_sa entries[], - unsigned nb_entries) + uint32_t nb_entries) { return sa_add_rules(sa_ctx, entries, nb_entries, 1); } void -sa_init(struct socket_ctx *ctx, int socket_id, unsigned ep) +sa_init(struct socket_ctx *ctx, int32_t socket_id, uint32_t ep) { const struct ipsec_sa *sa_out_entries, *sa_in_entries; - unsigned nb_out_entries, nb_in_entries; + uint32_t nb_out_entries, nb_in_entries; const char *name; if (ctx == NULL) rte_exit(EXIT_FAILURE, "NULL context.\n"); - if (ctx->sa_ipv4_in != NULL) + if (ctx->sa_in != NULL) rte_exit(EXIT_FAILURE, "Inbound SA DB for socket %u already " "initialized\n", socket_id); - if (ctx->sa_ipv4_out != NULL) + if (ctx->sa_out != NULL) rte_exit(EXIT_FAILURE, "Outbound SA DB for socket %u already " "initialized\n", socket_id); if (ep == 0) { - sa_out_entries = sa_ep0_out; - nb_out_entries = RTE_DIM(sa_ep0_out); - sa_in_entries = sa_ep0_in; - nb_in_entries = RTE_DIM(sa_ep0_in); + sa_out_entries = sa_out; + nb_out_entries = RTE_DIM(sa_out); + sa_in_entries = sa_in; + nb_in_entries = RTE_DIM(sa_in); } else if (ep == 1) { - sa_out_entries = sa_ep1_out; - nb_out_entries = RTE_DIM(sa_ep1_out); - sa_in_entries = sa_ep1_in; - nb_in_entries = RTE_DIM(sa_ep1_in); + sa_out_entries = sa_in; + nb_out_entries = RTE_DIM(sa_in); + sa_in_entries = sa_out; + nb_in_entries = RTE_DIM(sa_out); } else rte_exit(EXIT_FAILURE, "Invalid EP value %u. " "Only 0 or 1 supported.\n", ep); - name = "sa_ipv4_in"; - ctx->sa_ipv4_in = sa_ipv4_create(name, socket_id); - if (ctx->sa_ipv4_in == NULL) + name = "sa_in"; + ctx->sa_in = sa_create(name, socket_id); + if (ctx->sa_in == NULL) rte_exit(EXIT_FAILURE, "Error [%d] creating SA context %s " "in socket %d\n", rte_errno, name, socket_id); - name = "sa_ipv4_out"; - ctx->sa_ipv4_out = sa_ipv4_create(name, socket_id); - if (ctx->sa_ipv4_out == NULL) + name = "sa_out"; + ctx->sa_out = sa_create(name, socket_id); + if (ctx->sa_out == NULL) rte_exit(EXIT_FAILURE, "Error [%d] creating SA context %s " "in socket %d\n", rte_errno, name, socket_id); - sa_in_add_rules(ctx->sa_ipv4_in, sa_in_entries, nb_in_entries); + sa_in_add_rules(ctx->sa_in, sa_in_entries, nb_in_entries); - sa_out_add_rules(ctx->sa_ipv4_out, sa_out_entries, nb_out_entries); + sa_out_add_rules(ctx->sa_out, sa_out_entries, nb_out_entries); } int @@ -402,38 +444,66 @@ inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx) return (sa_ctx->sa[sa_idx].spi == priv->sa->spi); } +static inline void +single_inbound_lookup(struct ipsec_sa *sadb, struct rte_mbuf *pkt, + struct ipsec_sa **sa_ret) +{ + struct esp_hdr *esp; + struct ip *ip; + uint32_t *src4_addr; + uint8_t *src6_addr; + struct ipsec_sa *sa; + + *sa_ret = NULL; + + ip = rte_pktmbuf_mtod(pkt, struct ip *); + if (ip->ip_v == IPVERSION) + esp = (struct esp_hdr *)(ip + 1); + else + esp = (struct esp_hdr *)(((struct ip6_hdr *)ip) + 1); + + if (esp->spi == INVALID_SPI) + return; + + sa = &sadb[SPI2IDX(rte_be_to_cpu_32(esp->spi))]; + if (rte_be_to_cpu_32(esp->spi) != sa->spi) + return; + + switch (sa->flags) { + case IP4_TUNNEL: + src4_addr = RTE_PTR_ADD(ip, offsetof(struct ip, ip_src)); + if ((ip->ip_v == IPVERSION) && + (sa->src.ip4 == *src4_addr) && + (sa->dst.ip4 == *(src4_addr + 1))) + *sa_ret = sa; + 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.ip6, src6_addr, 16) && + !memcmp(&sa->dst.ip6, src6_addr + 16, 16)) + *sa_ret = sa; + break; + case TRANSPORT: + *sa_ret = sa; + } +} + void inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[], struct ipsec_sa *sa[], uint16_t nb_pkts) { - unsigned i; - uint32_t *src, spi; + uint32_t i; - for (i = 0; i < nb_pkts; i++) { - spi = rte_pktmbuf_mtod_offset(pkts[i], struct esp_hdr *, - sizeof(struct ip))->spi; - - if (spi == INVALID_SPI) - continue; - - sa[i] = &sa_ctx->sa[SPI2IDX(spi)]; - if (spi != sa[i]->spi) { - sa[i] = NULL; - continue; - } - - src = rte_pktmbuf_mtod_offset(pkts[i], uint32_t *, - offsetof(struct ip, ip_src)); - if ((sa[i]->src != *src) || (sa[i]->dst != *(src + 1))) - sa[i] = NULL; - } + for (i = 0; i < nb_pkts; i++) + single_inbound_lookup(sa_ctx->sa, pkts[i], &sa[i]); } void outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[], struct ipsec_sa *sa[], uint16_t nb_pkts) { - unsigned i; + uint32_t i; for (i = 0; i < nb_pkts; i++) sa[i] = &sa_ctx->sa[sa_idx[i]];