API Reference Manual 1.51.0
Loading...
Searching...
No Matches
ipsec_api/odp_ipsec_sa_db.c
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2014-2018 Linaro Limited
3 */
4
7/* enable strtok */
8#ifndef _GNU_SOURCE
9#define _GNU_SOURCE
10#endif
11
12#include <stdlib.h>
13#include <string.h>
14
15#include <odp_api.h>
16#include <odp/helper/odph_api.h>
17
18#include <odp_ipsec_sa_db.h>
19
20odp_bool_t sa_config_supported(const sa_db_entry_t *sa, int *sa_flags);
21
23static sa_db_t *sa_db;
24
26static tun_db_t *tun_db;
27
28void init_sa_db(void)
29{
30 odp_shm_t shm;
31
32 shm = odp_shm_reserve("shm_sa_db",
33 sizeof(sa_db_t),
34 ODP_CACHE_LINE_SIZE,
35 0);
36
37 if (shm == ODP_SHM_INVALID) {
38 ODPH_ERR("Error: shared mem reserve failed.\n");
39 exit(EXIT_FAILURE);
40 }
41
42 sa_db = odp_shm_addr(shm);
43
44 if (sa_db == NULL) {
45 ODPH_ERR("Error: shared mem alloc failed.\n");
46 exit(EXIT_FAILURE);
47 }
48 memset(sa_db, 0, sizeof(*sa_db));
49}
50
51void init_tun_db(void)
52{
53 odp_shm_t shm;
54
55 shm = odp_shm_reserve("shm_tun_db",
56 sizeof(tun_db_t),
57 ODP_CACHE_LINE_SIZE,
58 0);
59
60 if (shm == ODP_SHM_INVALID) {
61 ODPH_ERR("Error: shared mem reserve failed.\n");
62 exit(EXIT_FAILURE);
63 }
64
65 tun_db = odp_shm_addr(shm);
66
67 if (!tun_db) {
68 ODPH_ERR("Error: shared mem alloc failed.\n");
69 exit(EXIT_FAILURE);
70 }
71 memset(tun_db, 0, sizeof(*tun_db));
72}
73
74int create_sa_db_entry(char *input, odp_bool_t cipher)
75{
76 int pos = 0;
77 char *local;
78 char *str;
79 char *save;
80 char *token;
81 sa_db_entry_t *entry = &sa_db->array[sa_db->index];
82
83 /* Verify we have a good entry */
84 if (MAX_DB <= sa_db->index)
85 return -1;
86
87 /* Make a local copy */
88 local = malloc(strlen(input) + 1);
89 if (NULL == local)
90 return -1;
91 strcpy(local, input);
92
93 /* Set cipher versus auth */
94 entry->alg.cipher = cipher;
95
96 /* Setup for using "strtok_r" to search input string */
97 str = local;
98 save = NULL;
99
100 /* Parse tokens separated by ',' */
101 while (NULL != (token = strtok_r(str, ",", &save))) {
102 str = NULL; /* reset str for subsequent strtok_r calls */
103
104 /* Parse token based on its position */
105 switch (pos) {
106 case 0:
107 parse_ipv4_string(token, &entry->src_ip, NULL);
108 break;
109 case 1:
110 parse_ipv4_string(token, &entry->dst_ip, NULL);
111 break;
112 case 2:
113 if (cipher) {
114 if (0 == strcmp(token, "3des")) {
115 entry->alg.u.cipher =
117 entry->block_len = 8;
118 entry->iv_len = 8;
119 } else {
120 entry->alg.u.cipher =
122 }
123 } else {
124 if (0 == strcmp(token, "md5")) {
125 entry->alg.u.auth =
127 entry->icv_len = 12;
128 } else if (!strcmp(token, "sha1")) {
129 entry->alg.u.auth =
131 entry->icv_len = 12;
132 } else if (!strcmp(token, "sha256")) {
133 entry->alg.u.auth =
135 entry->icv_len = 16;
136 } else {
137 entry->alg.u.auth = ODP_AUTH_ALG_NULL;
138 }
139 }
140 break;
141 case 3:
142 entry->spi = strtol(token, NULL, 16);
143 break;
144 case 4:
145 parse_key_string(token,
146 &entry->key,
147 &entry->alg);
148 break;
149 default:
150 printf("ERROR: extra token \"%s\" at position %d\n",
151 token, pos);
152 break;
153 }
154
155 /* Advance to next position */
156 pos++;
157 }
158
159 /* Verify we parsed exactly the number of tokens we expected */
160 if (5 != pos) {
161 printf("ERROR: \"%s\" contains %d tokens, expected 5\n",
162 input,
163 pos);
164 free(local);
165 return -1;
166 }
167
168 if (!sa_config_supported(entry, &entry->flags)) {
169 free(local);
170 return -1;
171 }
172
173 /* Add route to the list */
174 sa_db->index++;
175 entry->next = sa_db->list;
176 sa_db->list = entry;
177
178 free(local);
179 return 0;
180}
181
182int create_tun_db_entry(char *input)
183{
184 int pos = 0;
185 char *local;
186 char *str;
187 char *save;
188 char *token;
189 tun_db_entry_t *entry = &tun_db->array[tun_db->index];
190
191 /* Verify we have a good entry */
192 if (MAX_DB <= tun_db->index)
193 return -1;
194
195 /* Make a local copy */
196 local = malloc(strlen(input) + 1);
197 if (NULL == local)
198 return -1;
199 strcpy(local, input);
200
201 /* Setup for using "strtok_r" to search input string */
202 str = local;
203 save = NULL;
204
205 /* Parse tokens separated by ',' */
206 while (NULL != (token = strtok_r(str, ",", &save))) {
207 str = NULL; /* reset str for subsequent strtok_r calls */
208
209 /* Parse token based on its position */
210 switch (pos) {
211 case 0:
212 parse_ipv4_string(token, &entry->src_ip, NULL);
213 break;
214 case 1:
215 parse_ipv4_string(token, &entry->dst_ip, NULL);
216 break;
217 case 2:
218 parse_ipv4_string(token, &entry->tun_src_ip, NULL);
219 break;
220 case 3:
221 parse_ipv4_string(token, &entry->tun_dst_ip, NULL);
222 break;
223 default:
224 printf("ERROR: extra token \"%s\" at position %d\n",
225 token, pos);
226 break;
227 }
228 pos++;
229 }
230
231 /* Verify we parsed exactly the number of tokens we expected */
232 if (4 != pos) {
233 printf("ERROR: \"%s\" contains %d tokens, expected 4\n",
234 input,
235 pos);
236 free(local);
237 return -1;
238 }
239
240 /* Add route to the list */
241 tun_db->index++;
242 entry->next = tun_db->list;
243 tun_db->list = entry;
244
245 free(local);
246 return 0;
247}
248
249tun_db_entry_t *find_tun_db_entry(uint32_t ip_src,
250 uint32_t ip_dst)
251{
252 tun_db_entry_t *entry = NULL;
253
254 /* Scan all entries and return first match */
255 for (entry = tun_db->list; NULL != entry; entry = entry->next) {
256 if (entry->src_ip != ip_src)
257 continue;
258 if (entry->dst_ip != ip_dst)
259 continue;
260 break;
261 }
262 return entry;
263}
264
265void dump_sa_db(void)
266{
267 sa_db_entry_t *entry;
268
269 printf("\n"
270 "Security association table\n"
271 "--------------------------\n");
272
273 for (entry = sa_db->list; NULL != entry; entry = entry->next) {
274 uint32_t idx;
275 char src_ip_str[MAX_STRING];
276 char dst_ip_str[MAX_STRING];
277 uint8_t *p = entry->key.data;
278
279
280 printf(" %s %s %s %X %d ",
281 entry->alg.cipher ? "esp" : "ah ",
282 ipv4_addr_str(src_ip_str, entry->src_ip),
283 ipv4_addr_str(dst_ip_str, entry->dst_ip),
284 entry->spi,
285 entry->alg.cipher ?
286 (int)entry->alg.u.cipher :
287 (int)entry->alg.u.auth);
288
289 /* Brute force key display */
290 for (idx = 0; idx < entry->key.length; idx++)
291 printf("%02X", *p++);
292
293 printf("\n");
294 }
295}
296
297sa_db_entry_t *find_sa_db_entry(ip_addr_range_t *src,
298 ip_addr_range_t *dst,
299 odp_bool_t cipher)
300{
301 sa_db_entry_t *entry = NULL;
302
303 /* Scan all entries and return first match */
304 for (entry = sa_db->list; NULL != entry; entry = entry->next) {
305 if (cipher != entry->alg.cipher)
306 continue;
307 if (!match_ip_range(entry->src_ip, src))
308 continue;
309 if (!match_ip_range(entry->dst_ip, dst))
310 continue;
311 break;
312 }
313 return entry;
314}
315
316void dump_tun_db(void)
317{
318 tun_db_entry_t *entry;
319
320 printf("\n"
321 "Tunnel table\n"
322 "--------------------------\n");
323
324 for (entry = tun_db->list; NULL != entry; entry = entry->next) {
325 char src_ip_str[MAX_STRING];
326 char dst_ip_str[MAX_STRING];
327 char tun_src_ip_str[MAX_STRING];
328 char tun_dst_ip_str[MAX_STRING];
329
330 printf(" %s:%s %s:%s ",
331 ipv4_addr_str(src_ip_str, entry->src_ip),
332 ipv4_addr_str(dst_ip_str, entry->dst_ip),
333 ipv4_addr_str(tun_src_ip_str, entry->tun_src_ip),
334 ipv4_addr_str(tun_dst_ip_str, entry->tun_dst_ip)
335 );
336
337 printf("\n");
338 }
339}
@ ODP_CIPHER_ALG_3DES_CBC
Triple DES with cipher block chaining.
@ ODP_CIPHER_ALG_NULL
No cipher algorithm specified.
@ ODP_AUTH_ALG_NULL
No authentication algorithm specified.
@ ODP_AUTH_ALG_MD5_HMAC
HMAC-MD5.
@ ODP_AUTH_ALG_SHA1_HMAC
HMAC-SHA-1.
@ ODP_AUTH_ALG_SHA256_HMAC
HMAC-SHA-256.
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.