1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019 Intel Corporation
6 #include <rte_malloc.h>
11 RTE_DEFINE_PER_LCORE(struct ipsec_sad_cache, sad_cache) = {
18 ipsec_sad_add(struct ipsec_sad *sad, struct ipsec_sa *sa)
22 union rte_ipsec_sad_key key = { {0} };
23 const union rte_ipsec_sad_key *lookup_key[1];
25 /* spi field is common for ipv4 and ipv6 key types */
26 key.v4.spi = rte_cpu_to_be_32(sa->spi);
28 switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) {
30 rte_ipsec_sad_lookup(sad->sad_v4, lookup_key, &tmp, 1);
34 ret = rte_ipsec_sad_add(sad->sad_v4, &key,
35 RTE_IPSEC_SAD_SPI_ONLY, sa);
40 rte_ipsec_sad_lookup(sad->sad_v6, lookup_key, &tmp, 1);
44 ret = rte_ipsec_sad_add(sad->sad_v6, &key,
45 RTE_IPSEC_SAD_SPI_ONLY, sa);
50 if (sp4_spi_present(sa->spi, 1, NULL, NULL) >= 0) {
51 rte_ipsec_sad_lookup(sad->sad_v4, lookup_key, &tmp, 1);
55 ret = rte_ipsec_sad_add(sad->sad_v4, &key,
56 RTE_IPSEC_SAD_SPI_ONLY, sa);
60 if (sp6_spi_present(sa->spi, 1, NULL, NULL) >= 0) {
61 rte_ipsec_sad_lookup(sad->sad_v6, lookup_key, &tmp, 1);
65 ret = rte_ipsec_sad_add(sad->sad_v6, &key,
66 RTE_IPSEC_SAD_SPI_ONLY, sa);
76 * Init per lcore SAD cache.
77 * Must be called by every processing lcore.
80 ipsec_sad_lcore_cache_init(uint32_t nb_cache_ent)
84 struct ipsec_sad_cache *cache;
86 cache = &RTE_PER_LCORE(sad_cache);
88 cache_elem = rte_align32pow2(nb_cache_ent);
89 cache_mem_sz = sizeof(struct ipsec_sa *) * cache_elem;
91 if (cache_mem_sz != 0) {
92 cache->v4 = rte_zmalloc_socket(NULL, cache_mem_sz,
93 RTE_CACHE_LINE_SIZE, rte_socket_id());
94 if (cache->v4 == NULL)
97 cache->v6 = rte_zmalloc_socket(NULL, cache_mem_sz,
98 RTE_CACHE_LINE_SIZE, rte_socket_id());
99 if (cache->v6 == NULL)
102 cache->mask = cache_elem - 1;
109 ipsec_sad_create(const char *name, struct ipsec_sad *sad,
110 int socket_id, struct ipsec_sa_cnt *sa_cnt)
113 struct rte_ipsec_sad_conf sad_conf;
114 char sad_name[RTE_IPSEC_SAD_NAMESIZE];
116 if ((name == NULL) || (sad == NULL) || (sa_cnt == NULL))
119 ret = snprintf(sad_name, RTE_IPSEC_SAD_NAMESIZE, "%s_v4", name);
120 if (ret < 0 || ret >= RTE_IPSEC_SAD_NAMESIZE)
121 return -ENAMETOOLONG;
123 sad_conf.socket_id = socket_id;
125 /* Make SAD have extra 25% of required number of entries */
126 sad_conf.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = sa_cnt->nb_v4 * 5 / 4;
127 sad_conf.max_sa[RTE_IPSEC_SAD_SPI_DIP] = 0;
128 sad_conf.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = 0;
130 if (sa_cnt->nb_v4 != 0) {
131 sad->sad_v4 = rte_ipsec_sad_create(sad_name, &sad_conf);
132 if (sad->sad_v4 == NULL)
136 ret = snprintf(sad_name, RTE_IPSEC_SAD_NAMESIZE, "%s_v6", name);
137 if (ret < 0 || ret >= RTE_IPSEC_SAD_NAMESIZE)
138 return -ENAMETOOLONG;
139 sad_conf.flags = RTE_IPSEC_SAD_FLAG_IPV6;
140 sad_conf.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = sa_cnt->nb_v6 * 5 / 4;
142 if (sa_cnt->nb_v6 != 0) {
143 sad->sad_v6 = rte_ipsec_sad_create(name, &sad_conf);
144 if (sad->sad_v6 == NULL)