API Reference Manual 1.51.0
Loading...
Searching...
No Matches
ipsec_api/odp_ipsec_cache.c
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2014-2018 Linaro Limited
3 */
4
7#include <stdlib.h>
8#include <string.h>
9
10#include <odp_api.h>
11#include <odp/helper/odph_api.h>
12
13#include <odp_ipsec_cache.h>
14
16ipsec_cache_t *ipsec_cache;
17
18void init_ipsec_cache(void)
19{
20 odp_shm_t shm;
21 int i;
22
23 shm = odp_shm_reserve("shm_ipsec_cache",
24 sizeof(ipsec_cache_t),
25 ODP_CACHE_LINE_SIZE,
26 0);
27
28 if (shm == ODP_SHM_INVALID) {
29 ODPH_ERR("Error: shared mem reserve failed.\n");
30 exit(EXIT_FAILURE);
31 }
32
33 ipsec_cache = odp_shm_addr(shm);
34
35 if (ipsec_cache == NULL) {
36 ODPH_ERR("Error: shared mem alloc failed.\n");
37 exit(EXIT_FAILURE);
38 }
39 memset(ipsec_cache, 0, sizeof(*ipsec_cache));
40
41 for (i = 0; i < MAX_DB; i++)
42 ipsec_cache->array[i].ipsec_sa = ODP_IPSEC_SA_INVALID;
43}
44
45int create_ipsec_cache_entry(sa_db_entry_t *cipher_sa,
46 sa_db_entry_t *auth_sa,
47 tun_db_entry_t *tun,
48 odp_bool_t in,
49 odp_queue_t completionq)
50{
52 ipsec_cache_entry_t *entry;
53 odp_ipsec_sa_t ipsec_sa;
54 uint32_t tun_src_ip, tun_dst_ip;
55 sa_mode_t mode = IPSEC_SA_MODE_TRANSPORT;
56
57 /* Verify we have a good entry */
58 entry = &ipsec_cache->array[ipsec_cache->index];
59 if (MAX_DB <= ipsec_cache->index)
60 return -1;
61
66 param.proto = cipher_sa ? ODP_IPSEC_ESP : ODP_IPSEC_AH;
67
69
70 param.dest_queue = completionq;
71
72 /* Cipher */
73 if (cipher_sa) {
74 param.crypto.cipher_alg = cipher_sa->alg.u.cipher;
75 param.crypto.cipher_key.data = cipher_sa->key.data;
76 param.crypto.cipher_key.length = cipher_sa->key.length;
77 param.spi = cipher_sa->spi;
78 } else {
80 }
81
82 /* Auth */
83 if (auth_sa) {
84 param.crypto.auth_alg = auth_sa->alg.u.auth;
85 param.crypto.auth_key.data = auth_sa->key.data;
86 param.crypto.auth_key.length = auth_sa->key.length;
87 param.spi = auth_sa->spi;
88 } else {
90 }
91
92 if (ODP_IPSEC_MODE_TUNNEL == param.mode) {
93 tun_src_ip = odp_cpu_to_be_32(tun->tun_src_ip);
94 tun_dst_ip = odp_cpu_to_be_32(tun->tun_dst_ip);
96 param.outbound.tunnel.ipv4.src_addr = &tun_src_ip;
97 param.outbound.tunnel.ipv4.dst_addr = &tun_dst_ip;
98 }
99
100 ipsec_sa = odp_ipsec_sa_create(&param);
101 if (ODP_IPSEC_SA_INVALID == ipsec_sa) {
102 ODPH_ERR("Error: SA creation failed\n");
103 exit(EXIT_FAILURE);
104 }
105
106 /* Copy remainder */
107 if (cipher_sa) {
108 entry->src_ip = cipher_sa->src_ip;
109 entry->dst_ip = cipher_sa->dst_ip;
110 entry->esp.alg = cipher_sa->alg.u.cipher;
111 entry->esp.spi = cipher_sa->spi;
112 entry->esp.block_len = cipher_sa->block_len;
113 entry->esp.iv_len = cipher_sa->iv_len;
114 memcpy(&entry->esp.key, &cipher_sa->key, sizeof(ipsec_key_t));
115 }
116 if (auth_sa) {
117 entry->src_ip = auth_sa->src_ip;
118 entry->dst_ip = auth_sa->dst_ip;
119 entry->ah.alg = auth_sa->alg.u.auth;
120 entry->ah.spi = auth_sa->spi;
121 entry->ah.icv_len = auth_sa->icv_len;
122 memcpy(&entry->ah.key, &auth_sa->key, sizeof(ipsec_key_t));
123 }
124
125 if (tun) {
126 entry->tun_src_ip = tun->tun_src_ip;
127 entry->tun_dst_ip = tun->tun_dst_ip;
128 mode = IPSEC_SA_MODE_TUNNEL;
129 }
130 entry->mode = mode;
131
132 /* Add entry to the appropriate list */
133 ipsec_cache->index++;
134 if (in) {
135 entry->next = ipsec_cache->in_list;
136 ipsec_cache->in_list = entry;
137 } else {
138 entry->next = ipsec_cache->out_list;
139 ipsec_cache->out_list = entry;
140 }
141
142 entry->ipsec_sa = ipsec_sa;
143
144 return 0;
145}
146
147ipsec_cache_entry_t *find_ipsec_cache_entry_in(uint32_t src_ip,
148 uint32_t dst_ip,
149 odph_ahhdr_t *ah,
150 odph_esphdr_t *esp)
151{
152 ipsec_cache_entry_t *entry = ipsec_cache->in_list;
153
154 /* Look for a hit */
155 for (; NULL != entry; entry = entry->next) {
156 if ((entry->src_ip != src_ip) || (entry->dst_ip != dst_ip))
157 if ((entry->tun_src_ip != src_ip) ||
158 (entry->tun_dst_ip != dst_ip))
159 continue;
160 if (ah &&
161 ((!entry->ah.alg) ||
162 (entry->ah.spi != odp_be_to_cpu_32(ah->spi))))
163 continue;
164 if (esp &&
165 ((!entry->esp.alg) ||
166 (entry->esp.spi != odp_be_to_cpu_32(esp->spi))))
167 continue;
168 break;
169 }
170
171 return entry;
172}
173
174ipsec_cache_entry_t *find_ipsec_cache_entry_out(uint32_t src_ip,
175 uint32_t dst_ip,
176 uint8_t proto ODP_UNUSED)
177{
178 ipsec_cache_entry_t *entry = ipsec_cache->out_list;
179
180 /* Look for a hit */
181 for (; NULL != entry; entry = entry->next) {
182 if ((entry->src_ip == src_ip) && (entry->dst_ip == dst_ip))
183 break;
184 }
185 return entry;
186}
187
188int destroy_ipsec_cache(void)
189{
190 ipsec_cache_entry_t *entry;
191 int i;
192 int ret = 0;
193
194 for (i = 0; i < MAX_DB; i++) {
195 entry = &ipsec_cache->array[i];
196 if (entry->ipsec_sa != ODP_IPSEC_SA_INVALID) {
197 ret += odp_ipsec_sa_disable(entry->ipsec_sa);
198 ret += odp_ipsec_sa_destroy(entry->ipsec_sa);
199 }
200 }
201
202 return ret;
203}
#define ODP_UNUSED
Intentionally unused variables of functions.
Definition spec/hints.h:54
odp_u32be_t odp_cpu_to_be_32(uint32_t cpu32)
Convert cpu native uint32_t to 32bit big endian.
uint32_t odp_be_to_cpu_32(odp_u32be_t be32)
Convert 32bit big endian to cpu native uint32_t.
@ ODP_CIPHER_ALG_NULL
No cipher algorithm specified.
@ ODP_AUTH_ALG_NULL
No authentication algorithm specified.
void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param)
Initialize IPSEC SA parameters.
int odp_ipsec_sa_disable(odp_ipsec_sa_t sa)
Disable IPSEC SA.
#define ODP_IPSEC_SA_INVALID
Invalid IPSEC SA.
odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
Create IPSEC SA.
int odp_ipsec_sa_destroy(odp_ipsec_sa_t sa)
Destroy IPSEC SA.
@ ODP_IPSEC_LOOKUP_SPI
Inbound SA lookup is enabled.
@ ODP_IPSEC_LOOKUP_DISABLED
Inbound SA lookup is disabled for the SA.
@ ODP_IPSEC_AH
AH protocol.
@ ODP_IPSEC_ESP
ESP protocol.
@ ODP_IPSEC_TUNNEL_IPV4
Outer header is IPv4.
@ ODP_IPSEC_MODE_TRANSPORT
IPSEC transport mode.
@ ODP_IPSEC_MODE_TUNNEL
IPSEC tunnel mode.
@ ODP_IPSEC_DIR_OUTBOUND
Outbound IPSEC SA.
@ ODP_IPSEC_DIR_INBOUND
Inbound IPSEC SA.
void * odp_shm_addr(odp_shm_t shm)
Shared memory block address.
#define ODP_SHM_INVALID
Invalid shared memory block.
odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags)
Reserve a contiguous block of shared memory.
bool odp_bool_t
Boolean type.
The OpenDataPlane API.
uint8_t * data
Key data.
uint32_t length
Key length in bytes.
odp_crypto_key_t auth_key
Authentication key.
odp_auth_alg_t auth_alg
Authentication algorithm.
odp_cipher_alg_t cipher_alg
Cipher algorithm.
odp_crypto_key_t cipher_key
Cipher key.
void * src_addr
IPv4 source address (NETWORK ENDIAN)
void * dst_addr
IPv4 destination address (NETWORK ENDIAN)
IPSEC Security Association (SA) parameters.
odp_ipsec_crypto_param_t crypto
Parameters for crypto and authentication algorithms.
odp_queue_t dest_queue
Destination queue for IPSEC events.
odp_ipsec_mode_t mode
IPSEC protocol mode: transport or tunnel.
struct odp_ipsec_sa_param_t::@52::@55 outbound
Outbound specific parameters.
struct odp_ipsec_sa_param_t::@52::@54 inbound
Inbound specific parameters.
odp_ipsec_dir_t dir
IPSEC SA direction: inbound or outbound.
odp_ipsec_tunnel_param_t tunnel
Parameters for tunnel mode.
odp_ipsec_protocol_t proto
IPSEC protocol: ESP or AH.
odp_ipsec_lookup_mode_t lookup_mode
SA lookup mode The default value is ODP_IPSEC_LOOKUP_DISABLED.
odp_ipsec_tunnel_type_t type
Tunnel type: IPv4 or IPv6.
odp_ipsec_ipv4_param_t ipv4
IPv4 header parameters.