xref: /dpdk/examples/ipsec-secgw/sad.c (revision 2cf67788ae895b4e3c05059e1feb06f6d3d8865e)
18e499dffSVladimir Medvedkin /* SPDX-License-Identifier: BSD-3-Clause
28e499dffSVladimir Medvedkin  * Copyright(c) 2019 Intel Corporation
38e499dffSVladimir Medvedkin  */
48e499dffSVladimir Medvedkin 
58e499dffSVladimir Medvedkin #include <rte_errno.h>
6*2cf67788SVladimir Medvedkin #include <rte_malloc.h>
78e499dffSVladimir Medvedkin 
88e499dffSVladimir Medvedkin #include "ipsec.h"
98e499dffSVladimir Medvedkin #include "sad.h"
108e499dffSVladimir Medvedkin 
11*2cf67788SVladimir Medvedkin RTE_DEFINE_PER_LCORE(struct ipsec_sad_cache, sad_cache) = {
12*2cf67788SVladimir Medvedkin 	.v4 = NULL,
13*2cf67788SVladimir Medvedkin 	.v6 = NULL,
14*2cf67788SVladimir Medvedkin 	.mask = 0,
15*2cf67788SVladimir Medvedkin };
16*2cf67788SVladimir Medvedkin 
178e499dffSVladimir Medvedkin int
ipsec_sad_add(struct ipsec_sad * sad,struct ipsec_sa * sa)188e499dffSVladimir Medvedkin ipsec_sad_add(struct ipsec_sad *sad, struct ipsec_sa *sa)
198e499dffSVladimir Medvedkin {
208e499dffSVladimir Medvedkin 	int ret;
218e499dffSVladimir Medvedkin 	void *tmp = NULL;
228e499dffSVladimir Medvedkin 	union rte_ipsec_sad_key key = { {0} };
238e499dffSVladimir Medvedkin 	const union rte_ipsec_sad_key *lookup_key[1];
248e499dffSVladimir Medvedkin 
258e499dffSVladimir Medvedkin 	/* spi field is common for ipv4 and ipv6 key types */
268e499dffSVladimir Medvedkin 	key.v4.spi = rte_cpu_to_be_32(sa->spi);
278e499dffSVladimir Medvedkin 	lookup_key[0] = &key;
288e499dffSVladimir Medvedkin 	switch (WITHOUT_TRANSPORT_VERSION(sa->flags)) {
298e499dffSVladimir Medvedkin 	case IP4_TUNNEL:
308e499dffSVladimir Medvedkin 		rte_ipsec_sad_lookup(sad->sad_v4, lookup_key, &tmp, 1);
318e499dffSVladimir Medvedkin 		if (tmp != NULL)
328e499dffSVladimir Medvedkin 			return -EEXIST;
338e499dffSVladimir Medvedkin 
348e499dffSVladimir Medvedkin 		ret = rte_ipsec_sad_add(sad->sad_v4, &key,
358e499dffSVladimir Medvedkin 			RTE_IPSEC_SAD_SPI_ONLY, sa);
368e499dffSVladimir Medvedkin 		if (ret != 0)
378e499dffSVladimir Medvedkin 			return ret;
388e499dffSVladimir Medvedkin 		break;
398e499dffSVladimir Medvedkin 	case IP6_TUNNEL:
408e499dffSVladimir Medvedkin 		rte_ipsec_sad_lookup(sad->sad_v6, lookup_key, &tmp, 1);
418e499dffSVladimir Medvedkin 		if (tmp != NULL)
428e499dffSVladimir Medvedkin 			return -EEXIST;
438e499dffSVladimir Medvedkin 
448e499dffSVladimir Medvedkin 		ret = rte_ipsec_sad_add(sad->sad_v6, &key,
458e499dffSVladimir Medvedkin 			RTE_IPSEC_SAD_SPI_ONLY, sa);
468e499dffSVladimir Medvedkin 		if (ret != 0)
478e499dffSVladimir Medvedkin 			return ret;
488e499dffSVladimir Medvedkin 		break;
498e499dffSVladimir Medvedkin 	case TRANSPORT:
508e499dffSVladimir Medvedkin 		if (sp4_spi_present(sa->spi, 1, NULL, NULL) >= 0) {
518e499dffSVladimir Medvedkin 			rte_ipsec_sad_lookup(sad->sad_v4, lookup_key, &tmp, 1);
528e499dffSVladimir Medvedkin 			if (tmp != NULL)
538e499dffSVladimir Medvedkin 				return -EEXIST;
548e499dffSVladimir Medvedkin 
558e499dffSVladimir Medvedkin 			ret = rte_ipsec_sad_add(sad->sad_v4, &key,
568e499dffSVladimir Medvedkin 				RTE_IPSEC_SAD_SPI_ONLY, sa);
578e499dffSVladimir Medvedkin 			if (ret != 0)
588e499dffSVladimir Medvedkin 				return ret;
598e499dffSVladimir Medvedkin 		}
608e499dffSVladimir Medvedkin 		if (sp6_spi_present(sa->spi, 1, NULL, NULL) >= 0) {
618e499dffSVladimir Medvedkin 			rte_ipsec_sad_lookup(sad->sad_v6, lookup_key, &tmp, 1);
628e499dffSVladimir Medvedkin 			if (tmp != NULL)
638e499dffSVladimir Medvedkin 				return -EEXIST;
648e499dffSVladimir Medvedkin 
658e499dffSVladimir Medvedkin 			ret = rte_ipsec_sad_add(sad->sad_v6, &key,
668e499dffSVladimir Medvedkin 				RTE_IPSEC_SAD_SPI_ONLY, sa);
678e499dffSVladimir Medvedkin 			if (ret != 0)
688e499dffSVladimir Medvedkin 				return ret;
698e499dffSVladimir Medvedkin 		}
708e499dffSVladimir Medvedkin 	}
718e499dffSVladimir Medvedkin 
728e499dffSVladimir Medvedkin 	return 0;
738e499dffSVladimir Medvedkin }
748e499dffSVladimir Medvedkin 
75*2cf67788SVladimir Medvedkin /*
76*2cf67788SVladimir Medvedkin  * Init per lcore SAD cache.
77*2cf67788SVladimir Medvedkin  * Must be called by every processing lcore.
78*2cf67788SVladimir Medvedkin  */
79*2cf67788SVladimir Medvedkin int
ipsec_sad_lcore_cache_init(uint32_t nb_cache_ent)80*2cf67788SVladimir Medvedkin ipsec_sad_lcore_cache_init(uint32_t nb_cache_ent)
81*2cf67788SVladimir Medvedkin {
82*2cf67788SVladimir Medvedkin 	uint32_t cache_elem;
83*2cf67788SVladimir Medvedkin 	size_t cache_mem_sz;
84*2cf67788SVladimir Medvedkin 	struct ipsec_sad_cache *cache;
85*2cf67788SVladimir Medvedkin 
86*2cf67788SVladimir Medvedkin 	cache = &RTE_PER_LCORE(sad_cache);
87*2cf67788SVladimir Medvedkin 
88*2cf67788SVladimir Medvedkin 	cache_elem = rte_align32pow2(nb_cache_ent);
89*2cf67788SVladimir Medvedkin 	cache_mem_sz = sizeof(struct ipsec_sa *) * cache_elem;
90*2cf67788SVladimir Medvedkin 
91*2cf67788SVladimir Medvedkin 	if (cache_mem_sz != 0) {
92*2cf67788SVladimir Medvedkin 		cache->v4 = rte_zmalloc_socket(NULL, cache_mem_sz,
93*2cf67788SVladimir Medvedkin 			RTE_CACHE_LINE_SIZE, rte_socket_id());
94*2cf67788SVladimir Medvedkin 		if (cache->v4 == NULL)
95*2cf67788SVladimir Medvedkin 			return -rte_errno;
96*2cf67788SVladimir Medvedkin 
97*2cf67788SVladimir Medvedkin 		cache->v6 = rte_zmalloc_socket(NULL, cache_mem_sz,
98*2cf67788SVladimir Medvedkin 			RTE_CACHE_LINE_SIZE, rte_socket_id());
99*2cf67788SVladimir Medvedkin 		if (cache->v6 == NULL)
100*2cf67788SVladimir Medvedkin 			return -rte_errno;
101*2cf67788SVladimir Medvedkin 
102*2cf67788SVladimir Medvedkin 		cache->mask = cache_elem - 1;
103*2cf67788SVladimir Medvedkin 	}
104*2cf67788SVladimir Medvedkin 
105*2cf67788SVladimir Medvedkin 	return 0;
106*2cf67788SVladimir Medvedkin }
107*2cf67788SVladimir Medvedkin 
1088e499dffSVladimir Medvedkin int
ipsec_sad_create(const char * name,struct ipsec_sad * sad,int socket_id,struct ipsec_sa_cnt * sa_cnt)1098e499dffSVladimir Medvedkin ipsec_sad_create(const char *name, struct ipsec_sad *sad,
1108e499dffSVladimir Medvedkin 	int socket_id, struct ipsec_sa_cnt *sa_cnt)
1118e499dffSVladimir Medvedkin {
1128e499dffSVladimir Medvedkin 	int ret;
1138e499dffSVladimir Medvedkin 	struct rte_ipsec_sad_conf sad_conf;
1148e499dffSVladimir Medvedkin 	char sad_name[RTE_IPSEC_SAD_NAMESIZE];
1158e499dffSVladimir Medvedkin 
1168e499dffSVladimir Medvedkin 	if ((name == NULL) || (sad == NULL) || (sa_cnt == NULL))
1178e499dffSVladimir Medvedkin 		return -EINVAL;
1188e499dffSVladimir Medvedkin 
1198e499dffSVladimir Medvedkin 	ret = snprintf(sad_name, RTE_IPSEC_SAD_NAMESIZE, "%s_v4", name);
1208e499dffSVladimir Medvedkin 	if (ret < 0 || ret >= RTE_IPSEC_SAD_NAMESIZE)
1218e499dffSVladimir Medvedkin 		return -ENAMETOOLONG;
1228e499dffSVladimir Medvedkin 
1238e499dffSVladimir Medvedkin 	sad_conf.socket_id = socket_id;
1248e499dffSVladimir Medvedkin 	sad_conf.flags = 0;
1258e499dffSVladimir Medvedkin 	/* Make SAD have extra 25% of required number of entries */
1268e499dffSVladimir Medvedkin 	sad_conf.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = sa_cnt->nb_v4 * 5 / 4;
1278e499dffSVladimir Medvedkin 	sad_conf.max_sa[RTE_IPSEC_SAD_SPI_DIP] = 0;
1288e499dffSVladimir Medvedkin 	sad_conf.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = 0;
1298e499dffSVladimir Medvedkin 
1308e499dffSVladimir Medvedkin 	if (sa_cnt->nb_v4 != 0) {
1318e499dffSVladimir Medvedkin 		sad->sad_v4 = rte_ipsec_sad_create(sad_name, &sad_conf);
1328e499dffSVladimir Medvedkin 		if (sad->sad_v4 == NULL)
1338e499dffSVladimir Medvedkin 			return -rte_errno;
1348e499dffSVladimir Medvedkin 	}
1358e499dffSVladimir Medvedkin 
1368e499dffSVladimir Medvedkin 	ret = snprintf(sad_name, RTE_IPSEC_SAD_NAMESIZE, "%s_v6", name);
1378e499dffSVladimir Medvedkin 	if (ret < 0 || ret >= RTE_IPSEC_SAD_NAMESIZE)
1388e499dffSVladimir Medvedkin 		return -ENAMETOOLONG;
1398e499dffSVladimir Medvedkin 	sad_conf.flags = RTE_IPSEC_SAD_FLAG_IPV6;
1408e499dffSVladimir Medvedkin 	sad_conf.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = sa_cnt->nb_v6 * 5 / 4;
1418e499dffSVladimir Medvedkin 
1428e499dffSVladimir Medvedkin 	if (sa_cnt->nb_v6 != 0) {
1438e499dffSVladimir Medvedkin 		sad->sad_v6 = rte_ipsec_sad_create(name, &sad_conf);
1448e499dffSVladimir Medvedkin 		if (sad->sad_v6 == NULL)
1458e499dffSVladimir Medvedkin 			return -rte_errno;
1468e499dffSVladimir Medvedkin 	}
1478e499dffSVladimir Medvedkin 
1488e499dffSVladimir Medvedkin 	return 0;
1498e499dffSVladimir Medvedkin }
150