Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2019 Intel Corporation
3 : : */
4 : :
5 : : #include <rte_string_fns.h>
6 : : #include <rte_ipsec_sad.h>
7 : : #include <getopt.h>
8 : : #include <string.h>
9 : : #include <stdio.h>
10 : : #include <stdlib.h>
11 : : #include <sys/types.h>
12 : : #include <sys/socket.h>
13 : : #include <netinet/in.h>
14 : : #include <arpa/inet.h>
15 : :
16 : : #include <rte_cycles.h>
17 : : #include <rte_errno.h>
18 : : #include <rte_ip.h>
19 : : #include <rte_random.h>
20 : : #include <rte_malloc.h>
21 : :
22 : : #define PRINT_USAGE_START "%s [EAL options] --\n"
23 : :
24 : : #define GET_CB_FIELD(in, fd, base, lim, dlm) do { \
25 : : unsigned long val; \
26 : : char *end_fld; \
27 : : errno = 0; \
28 : : val = strtoul((in), &end_fld, (base)); \
29 : : if (errno != 0 || end_fld[0] != (dlm) || val > (lim)) \
30 : : return -EINVAL; \
31 : : (fd) = (typeof(fd))val; \
32 : : (in) = end_fld + 1; \
33 : : } while (0)
34 : :
35 : : #define DEF_RULE_NUM 0x10000
36 : : #define DEF_TUPLES_NUM 0x100000
37 : : #define BURST_SZ_MAX 64
38 : :
39 : : static struct {
40 : : const char *prgname;
41 : : const char *rules_file;
42 : : const char *tuples_file;
43 : : uint32_t nb_rules;
44 : : uint32_t nb_tuples;
45 : : uint32_t nb_rules_32;
46 : : uint32_t nb_rules_64;
47 : : uint32_t nb_rules_96;
48 : : uint32_t nb_tuples_rnd;
49 : : uint32_t burst_sz;
50 : : uint8_t fract_32;
51 : : uint8_t fract_64;
52 : : uint8_t fract_96;
53 : : uint8_t fract_rnd_tuples;
54 : : int ipv6;
55 : : int verbose;
56 : : int parallel_lookup;
57 : : int concurrent_rw;
58 : : } config = {
59 : : .rules_file = NULL,
60 : : .tuples_file = NULL,
61 : : .nb_rules = DEF_RULE_NUM,
62 : : .nb_tuples = DEF_TUPLES_NUM,
63 : : .nb_rules_32 = 0,
64 : : .nb_rules_64 = 0,
65 : : .nb_rules_96 = 0,
66 : : .nb_tuples_rnd = 0,
67 : : .burst_sz = BURST_SZ_MAX,
68 : : .fract_32 = 90,
69 : : .fract_64 = 9,
70 : : .fract_96 = 1,
71 : : .fract_rnd_tuples = 0,
72 : : .ipv6 = 0,
73 : : .verbose = 0,
74 : : .parallel_lookup = 0,
75 : : .concurrent_rw = 0
76 : : };
77 : :
78 : : enum {
79 : : CB_RULE_SPI,
80 : : CB_RULE_DIP,
81 : : CB_RULE_SIP,
82 : : CB_RULE_LEN,
83 : : CB_RULE_NUM,
84 : : };
85 : :
86 : : static char line[LINE_MAX];
87 : : struct rule {
88 : : union rte_ipsec_sad_key tuple;
89 : : int rule_type;
90 : : };
91 : :
92 : : static struct rule *rules_tbl;
93 : : static struct rule *tuples_tbl;
94 : :
95 : : static int
96 : 0 : parse_distrib(const char *in)
97 : : {
98 : : int a, b, c;
99 : :
100 : 0 : GET_CB_FIELD(in, a, 0, UINT8_MAX, '/');
101 : 0 : GET_CB_FIELD(in, b, 0, UINT8_MAX, '/');
102 : 0 : GET_CB_FIELD(in, c, 0, UINT8_MAX, 0);
103 : :
104 : 0 : if ((a + b + c) != 100)
105 : : return -EINVAL;
106 : :
107 : 0 : config.fract_32 = a;
108 : 0 : config.fract_64 = b;
109 : 0 : config.fract_96 = c;
110 : :
111 : 0 : return 0;
112 : : }
113 : :
114 : : static void
115 : 0 : print_config(void)
116 : : {
117 : 0 : fprintf(stdout,
118 : : "Rules total: %u\n"
119 : : "Configured rules distribution SPI/SPI_DIP/SIP_DIP_SIP:"
120 : : "%u/%u/%u\n"
121 : : "SPI only rules: %u\n"
122 : : "SPI_DIP rules: %u\n"
123 : : "SPI_DIP_SIP rules: %u\n"
124 : : "Lookup tuples: %u\n"
125 : : "Lookup burst size %u\n"
126 : : "Configured fraction of random tuples: %u\n"
127 : : "Random lookup tuples: %u\n",
128 : 0 : config.nb_rules, config.fract_32, config.fract_64,
129 : 0 : config.fract_96, config.nb_rules_32, config.nb_rules_64,
130 : : config.nb_rules_96, config.nb_tuples, config.burst_sz,
131 : 0 : config.fract_rnd_tuples, config.nb_tuples_rnd);
132 : 0 : }
133 : :
134 : : static void
135 : : print_usage(void)
136 : : {
137 : 0 : fprintf(stdout,
138 : : PRINT_USAGE_START
139 : : "[-f <rules file>]\n"
140 : : "[-t <tuples file for lookup>]\n"
141 : : "[-n <rules number (if -f is not specified)>]\n"
142 : : "[-l <lookup tuples number (if -t is not specified)>]\n"
143 : : "[-6 <ipv6 tests>]\n"
144 : : "[-d <\"/\" separated rules length distribution"
145 : : "(if -f is not specified)>]\n"
146 : : "[-r <random tuples fraction to lookup"
147 : : "(if -t is not specified)>]\n"
148 : : "[-b <lookup burst size: 1-64 >]\n"
149 : : "[-v <verbose, print results on lookup>]\n"
150 : : "[-p <parallel lookup on all available cores>]\n"
151 : : "[-c <init sad supporting read/write concurrency>]\n",
152 : : config.prgname);
153 : :
154 : : }
155 : :
156 : : static int
157 : 0 : get_str_num(FILE *f, int num)
158 : : {
159 : : int n_lines = 0;
160 : :
161 : 0 : if (f != NULL) {
162 : 0 : while (fgets(line, sizeof(line), f) != NULL)
163 : 0 : n_lines++;
164 : 0 : rewind(f);
165 : : } else {
166 : : n_lines = num;
167 : : }
168 : 0 : return n_lines;
169 : : }
170 : :
171 : : static int
172 : 0 : parse_file(FILE *f, struct rule *tbl, int rule_tbl)
173 : : {
174 : : int ret, i, j = 0;
175 : : char *s, *sp, *in[CB_RULE_NUM];
176 : : static const char *dlm = " \t\n";
177 : : int string_tok_nb = RTE_DIM(in);
178 : :
179 : 0 : string_tok_nb -= (rule_tbl == 0) ? 1 : 0;
180 : 0 : while (fgets(line, sizeof(line), f) != NULL) {
181 : : s = line;
182 : 0 : for (i = 0; i != string_tok_nb; i++) {
183 : 0 : in[i] = strtok_r(s, dlm, &sp);
184 : 0 : if (in[i] == NULL)
185 : : return -EINVAL;
186 : : s = NULL;
187 : : }
188 : 0 : GET_CB_FIELD(in[CB_RULE_SPI], tbl[j].tuple.v4.spi, 0,
189 : : UINT32_MAX, 0);
190 : :
191 : 0 : if (config.ipv6)
192 : 0 : ret = inet_pton(AF_INET6, in[CB_RULE_DIP],
193 : 0 : &tbl[j].tuple.v6.dip);
194 : : else
195 : 0 : ret = inet_pton(AF_INET, in[CB_RULE_DIP],
196 : 0 : &tbl[j].tuple.v4.dip);
197 : 0 : if (ret != 1)
198 : : return -EINVAL;
199 : 0 : if (config.ipv6)
200 : 0 : ret = inet_pton(AF_INET6, in[CB_RULE_SIP],
201 : 0 : &tbl[j].tuple.v6.sip);
202 : : else
203 : 0 : ret = inet_pton(AF_INET, in[CB_RULE_SIP],
204 : 0 : &tbl[j].tuple.v4.sip);
205 : 0 : if (ret != 1)
206 : : return -EINVAL;
207 : 0 : if ((rule_tbl) && (in[CB_RULE_LEN] != NULL)) {
208 : 0 : if (strcmp(in[CB_RULE_LEN], "SPI_DIP_SIP") == 0) {
209 : 0 : tbl[j].rule_type = RTE_IPSEC_SAD_SPI_DIP_SIP;
210 : 0 : config.nb_rules_96++;
211 : 0 : } else if (strcmp(in[CB_RULE_LEN], "SPI_DIP") == 0) {
212 : 0 : tbl[j].rule_type = RTE_IPSEC_SAD_SPI_DIP;
213 : 0 : config.nb_rules_64++;
214 : 0 : } else if (strcmp(in[CB_RULE_LEN], "SPI") == 0) {
215 : 0 : tbl[j].rule_type = RTE_IPSEC_SAD_SPI_ONLY;
216 : 0 : config.nb_rules_32++;
217 : : } else {
218 : : return -EINVAL;
219 : : }
220 : : }
221 : 0 : j++;
222 : : }
223 : : return 0;
224 : : }
225 : :
226 : : static uint64_t
227 : : get_rnd_rng(uint64_t l, uint64_t u)
228 : : {
229 : 0 : if (l == u)
230 : : return l;
231 : : else
232 : 0 : return (rte_rand() % (u - l) + l);
233 : : }
234 : :
235 : : static void
236 : 0 : get_random_rules(struct rule *tbl, uint32_t nb_rules, int rule_tbl)
237 : : {
238 : : unsigned int i, j, rnd;
239 : : int rule_type;
240 : : double edge = 0;
241 : : double step;
242 : :
243 : 0 : step = (double)UINT32_MAX / nb_rules;
244 : 0 : for (i = 0; i < nb_rules; i++, edge += step) {
245 : 0 : rnd = rte_rand() % 100;
246 : 0 : if (rule_tbl) {
247 : 0 : tbl[i].tuple.v4.spi = get_rnd_rng((uint64_t)edge,
248 : 0 : (uint64_t)(edge + step));
249 : 0 : if (config.ipv6) {
250 : 0 : for (j = 0; j < 16; j++) {
251 : 0 : tbl[i].tuple.v6.dip.a[j] = rte_rand();
252 : 0 : tbl[i].tuple.v6.sip.a[j] = rte_rand();
253 : : }
254 : : } else {
255 : 0 : tbl[i].tuple.v4.dip = rte_rand();
256 : 0 : tbl[i].tuple.v4.sip = rte_rand();
257 : : }
258 : 0 : if (rnd >= (100UL - config.fract_32)) {
259 : : rule_type = RTE_IPSEC_SAD_SPI_ONLY;
260 : 0 : config.nb_rules_32++;
261 : 0 : } else if (rnd >= (100UL - (config.fract_32 +
262 : 0 : config.fract_64))) {
263 : : rule_type = RTE_IPSEC_SAD_SPI_DIP;
264 : 0 : config.nb_rules_64++;
265 : : } else {
266 : : rule_type = RTE_IPSEC_SAD_SPI_DIP_SIP;
267 : 0 : config.nb_rules_96++;
268 : : }
269 : 0 : tbl[i].rule_type = rule_type;
270 : : } else {
271 : 0 : if (rnd >= 100UL - config.fract_rnd_tuples) {
272 : 0 : tbl[i].tuple.v4.spi =
273 : 0 : get_rnd_rng((uint64_t)edge,
274 : 0 : (uint64_t)(edge + step));
275 : 0 : if (config.ipv6) {
276 : 0 : for (j = 0; j < 16; j++) {
277 : 0 : tbl[i].tuple.v6.dip.a[j] =
278 : 0 : rte_rand();
279 : 0 : tbl[i].tuple.v6.sip.a[j] =
280 : 0 : rte_rand();
281 : : }
282 : : } else {
283 : 0 : tbl[i].tuple.v4.dip = rte_rand();
284 : 0 : tbl[i].tuple.v4.sip = rte_rand();
285 : : }
286 : 0 : config.nb_tuples_rnd++;
287 : : } else {
288 : 0 : tbl[i].tuple.v4.spi = rules_tbl[i %
289 : 0 : config.nb_rules].tuple.v4.spi;
290 : 0 : if (config.ipv6) {
291 : 0 : int r_idx = i % config.nb_rules;
292 : 0 : tbl[i].tuple.v6.dip = rules_tbl[r_idx].tuple.v6.dip;
293 : 0 : tbl[i].tuple.v6.sip = rules_tbl[r_idx].tuple.v6.sip;
294 : : } else {
295 : 0 : tbl[i].tuple.v4.dip = rules_tbl[i %
296 : 0 : config.nb_rules].tuple.v4.dip;
297 : 0 : tbl[i].tuple.v4.sip = rules_tbl[i %
298 : 0 : config.nb_rules].tuple.v4.sip;
299 : : }
300 : : }
301 : : }
302 : : }
303 : 0 : }
304 : :
305 : : static void
306 : 0 : tbl_init(struct rule **tbl, uint32_t *n_entries,
307 : : const char *file_name, int rule_tbl)
308 : : {
309 : : FILE *f = NULL;
310 : : int ret;
311 : : const char *rules = "rules";
312 : : const char *tuples = "tuples";
313 : :
314 : 0 : if (file_name != NULL) {
315 : 0 : f = fopen(file_name, "r");
316 : 0 : if (f == NULL)
317 : 0 : rte_exit(-EINVAL, "failed to open file: %s\n",
318 : : file_name);
319 : : }
320 : :
321 : 0 : printf("init %s table...", (rule_tbl) ? rules : tuples);
322 : 0 : *n_entries = get_str_num(f, *n_entries);
323 : : printf("%d entries\n", *n_entries);
324 : 0 : *tbl = rte_zmalloc(NULL, sizeof(struct rule) * *n_entries,
325 : : RTE_CACHE_LINE_SIZE);
326 : 0 : if (*tbl == NULL)
327 : 0 : rte_exit(-ENOMEM, "failed to allocate tbl\n");
328 : :
329 : 0 : if (f != NULL) {
330 : : printf("parse file %s\n", file_name);
331 : 0 : ret = parse_file(f, *tbl, rule_tbl);
332 : 0 : if (ret != 0)
333 : 0 : rte_exit(-EINVAL, "failed to parse file %s\n"
334 : : "rules file must be: "
335 : : "<uint32_t: spi> <space> "
336 : : "<ip_addr: dip> <space> "
337 : : "<ip_addr: sip> <space> "
338 : : "<string: SPI|SPI_DIP|SIP_DIP_SIP>\n"
339 : : "tuples file must be: "
340 : : "<uint32_t: spi> <space> "
341 : : "<ip_addr: dip> <space> "
342 : : "<ip_addr: sip>\n",
343 : : file_name);
344 : : } else {
345 : : printf("generate random values in %s table\n",
346 : : (rule_tbl) ? rules : tuples);
347 : 0 : get_random_rules(*tbl, *n_entries, rule_tbl);
348 : : }
349 : 0 : if (f != NULL)
350 : 0 : fclose(f);
351 : 0 : }
352 : :
353 : : static void
354 : 0 : parse_opts(int argc, char **argv)
355 : : {
356 : : int opt, ret;
357 : : char *endptr;
358 : :
359 : 0 : while ((opt = getopt(argc, argv, "f:t:n:d:l:r:6b:vpc")) != -1) {
360 : 0 : switch (opt) {
361 : 0 : case 'f':
362 : 0 : config.rules_file = optarg;
363 : 0 : break;
364 : 0 : case 't':
365 : 0 : config.tuples_file = optarg;
366 : 0 : break;
367 : 0 : case 'n':
368 : 0 : errno = 0;
369 : 0 : config.nb_rules = strtoul(optarg, &endptr, 10);
370 : 0 : if ((errno != 0) || (config.nb_rules == 0) ||
371 : 0 : (endptr[0] != 0)) {
372 : : print_usage();
373 : 0 : rte_exit(-EINVAL, "Invalid option -n\n");
374 : : }
375 : : break;
376 : 0 : case 'd':
377 : 0 : ret = parse_distrib(optarg);
378 : 0 : if (ret != 0) {
379 : : print_usage();
380 : 0 : rte_exit(-EINVAL, "Invalid option -d\n");
381 : : }
382 : : break;
383 : 0 : case 'b':
384 : 0 : errno = 0;
385 : 0 : config.burst_sz = strtoul(optarg, &endptr, 10);
386 : 0 : if ((errno != 0) || (config.burst_sz == 0) ||
387 : 0 : (config.burst_sz > BURST_SZ_MAX) ||
388 : 0 : (endptr[0] != 0)) {
389 : : print_usage();
390 : 0 : rte_exit(-EINVAL, "Invalid option -b\n");
391 : : }
392 : : break;
393 : 0 : case 'l':
394 : 0 : errno = 0;
395 : 0 : config.nb_tuples = strtoul(optarg, &endptr, 10);
396 : 0 : if ((errno != 0) || (config.nb_tuples == 0) ||
397 : 0 : (endptr[0] != 0)) {
398 : : print_usage();
399 : 0 : rte_exit(-EINVAL, "Invalid option -l\n");
400 : : }
401 : : break;
402 : 0 : case 'r':
403 : 0 : errno = 0;
404 : 0 : config.fract_rnd_tuples = strtoul(optarg, &endptr, 10);
405 : 0 : if ((errno != 0) || (config.fract_rnd_tuples == 0) ||
406 : 0 : (config.fract_rnd_tuples >= 100) ||
407 : 0 : (endptr[0] != 0)) {
408 : : print_usage();
409 : 0 : rte_exit(-EINVAL, "Invalid option -r\n");
410 : : }
411 : : break;
412 : 0 : case '6':
413 : 0 : config.ipv6 = 1;
414 : 0 : break;
415 : 0 : case 'v':
416 : 0 : config.verbose = 1;
417 : 0 : break;
418 : 0 : case 'p':
419 : 0 : config.parallel_lookup = 1;
420 : 0 : break;
421 : 0 : case 'c':
422 : 0 : config.concurrent_rw = 1;
423 : 0 : break;
424 : : default:
425 : : print_usage();
426 : 0 : rte_exit(-EINVAL, "Invalid options\n");
427 : : }
428 : : }
429 : 0 : }
430 : :
431 : : static void
432 : 0 : print_addr(int af, const void *addr)
433 : : {
434 : : char str[INET6_ADDRSTRLEN];
435 : : const char *ret;
436 : :
437 : 0 : ret = inet_ntop(af, addr, str, sizeof(str));
438 : 0 : if (ret != NULL)
439 : : printf("%s", str);
440 : 0 : }
441 : :
442 : : static void
443 : 0 : print_tuple(int af, uint32_t spi, const void *dip, const void *sip)
444 : : {
445 : :
446 : : printf("<SPI: %u DIP: ", spi);
447 : 0 : print_addr(af, dip);
448 : : printf(" SIP: ");
449 : 0 : print_addr(af, sip);
450 : : printf(">");
451 : 0 : }
452 : :
453 : : static void
454 : 0 : print_result(const union rte_ipsec_sad_key *key, void *res)
455 : : {
456 : : struct rule *rule = res;
457 : : const struct rte_ipsec_sadv4_key *v4;
458 : : const struct rte_ipsec_sadv6_key *v6;
459 : : const char *spi_only = "SPI_ONLY";
460 : : const char *spi_dip = "SPI_DIP";
461 : : const char *spi_dip_sip = "SPI_DIP_SIP";
462 : : const char *rule_type;
463 : : const void *dip, *sip;
464 : : uint32_t spi;
465 : : int af;
466 : :
467 : 0 : af = (config.ipv6) ? AF_INET6 : AF_INET;
468 : : v4 = &key->v4;
469 : : v6 = &key->v6;
470 : 0 : spi = (config.ipv6 == 0) ? v4->spi : v6->spi;
471 : 0 : dip = (config.ipv6 == 0) ? &v4->dip : (const void *)&v6->dip;
472 : 0 : sip = (config.ipv6 == 0) ? &v4->sip : (const void *)&v6->sip;
473 : :
474 : 0 : if (res == NULL) {
475 : : printf("TUPLE: ");
476 : 0 : print_tuple(af, spi, dip, sip);
477 : : printf(" not found\n");
478 : 0 : return;
479 : : }
480 : :
481 : 0 : switch (rule->rule_type) {
482 : : case RTE_IPSEC_SAD_SPI_ONLY:
483 : : rule_type = spi_only;
484 : : break;
485 : 0 : case RTE_IPSEC_SAD_SPI_DIP:
486 : : rule_type = spi_dip;
487 : 0 : break;
488 : 0 : case RTE_IPSEC_SAD_SPI_DIP_SIP:
489 : : rule_type = spi_dip_sip;
490 : 0 : break;
491 : : default:
492 : : return;
493 : : }
494 : :
495 : 0 : print_tuple(af, spi, dip, sip);
496 : : v4 = &rule->tuple.v4;
497 : : v6 = &rule->tuple.v6;
498 : 0 : spi = (config.ipv6 == 0) ? v4->spi : v6->spi;
499 : 0 : dip = (config.ipv6 == 0) ? &v4->dip : (const void *)&v6->dip;
500 : 0 : sip = (config.ipv6 == 0) ? &v4->sip : (const void *)&v6->sip;
501 : 0 : printf("\n\tpoints to RULE ID %zu ",
502 : 0 : RTE_PTR_DIFF(res, rules_tbl)/sizeof(struct rule));
503 : 0 : print_tuple(af, spi, dip, sip);
504 : : printf(" %s\n", rule_type);
505 : : }
506 : :
507 : : static int
508 : 0 : lookup(void *arg)
509 : : {
510 : : int ret;
511 : : unsigned int i, j;
512 : : const union rte_ipsec_sad_key *keys[BURST_SZ_MAX];
513 : : void *vals[BURST_SZ_MAX];
514 : : uint64_t start, acc = 0;
515 : : uint32_t burst_sz;
516 : : struct rte_ipsec_sad *sad = arg;
517 : :
518 : 0 : if (config.nb_tuples == 0)
519 : : return 0;
520 : :
521 : 0 : burst_sz = RTE_MIN(config.burst_sz, config.nb_tuples);
522 : 0 : for (i = 0; i < config.nb_tuples; i += burst_sz) {
523 : 0 : for (j = 0; j < burst_sz; j++)
524 : 0 : keys[j] = (union rte_ipsec_sad_key *)
525 : 0 : (&tuples_tbl[i + j].tuple);
526 : : start = rte_rdtsc_precise();
527 : 0 : ret = rte_ipsec_sad_lookup(sad, keys, vals, burst_sz);
528 : 0 : acc += rte_rdtsc_precise() - start;
529 : 0 : if (ret < 0)
530 : 0 : rte_exit(-EINVAL, "Lookup failed\n");
531 : 0 : if (config.verbose) {
532 : 0 : for (j = 0; j < burst_sz; j++)
533 : 0 : print_result(keys[j], vals[j]);
534 : : }
535 : : }
536 : 0 : acc = (acc == 0) ? UINT64_MAX : acc;
537 : 0 : printf("Average lookup cycles %.2Lf, lookups/sec: %.2Lf\n",
538 : 0 : (long double)acc / config.nb_tuples,
539 : 0 : (long double)config.nb_tuples * rte_get_tsc_hz() / acc);
540 : :
541 : 0 : return 0;
542 : : }
543 : :
544 : : static void
545 : 0 : add_rules(struct rte_ipsec_sad *sad, uint32_t fract)
546 : 0 : {
547 : : int32_t ret;
548 : : uint32_t i, j, f, fn, n;
549 : 0 : uint64_t start, tm[fract + 1];
550 : 0 : uint32_t nm[fract + 1];
551 : :
552 : 0 : f = (config.nb_rules > fract) ? config.nb_rules / fract : 1;
553 : :
554 : 0 : for (n = 0, j = 0; n != config.nb_rules; n = fn, j++) {
555 : :
556 : 0 : fn = n + f;
557 : 0 : fn = fn > config.nb_rules ? config.nb_rules : fn;
558 : :
559 : : start = rte_rdtsc_precise();
560 : 0 : for (i = n; i != fn; i++) {
561 : 0 : ret = rte_ipsec_sad_add(sad,
562 : 0 : &rules_tbl[i].tuple,
563 : 0 : rules_tbl[i].rule_type, &rules_tbl[i]);
564 : 0 : if (ret != 0)
565 : 0 : rte_exit(ret, "%s failed @ %u-th rule\n",
566 : : __func__, i);
567 : : }
568 : 0 : tm[j] = rte_rdtsc_precise() - start;
569 : 0 : nm[j] = fn - n;
570 : : }
571 : :
572 : 0 : for (i = 0; i != j; i++)
573 : 0 : printf("ADD %u rules, %.2Lf cycles/rule, %.2Lf ADD/sec\n",
574 : : nm[i], (long double)tm[i] / nm[i],
575 : 0 : (long double)nm[i] * rte_get_tsc_hz() / tm[i]);
576 : 0 : }
577 : :
578 : : static void
579 : 0 : del_rules(struct rte_ipsec_sad *sad, uint32_t fract)
580 : 0 : {
581 : : int32_t ret;
582 : : uint32_t i, j, f, fn, n;
583 : 0 : uint64_t start, tm[fract + 1];
584 : 0 : uint32_t nm[fract + 1];
585 : :
586 : 0 : f = (config.nb_rules > fract) ? config.nb_rules / fract : 1;
587 : :
588 : 0 : for (n = 0, j = 0; n != config.nb_rules; n = fn, j++) {
589 : :
590 : 0 : fn = n + f;
591 : 0 : fn = fn > config.nb_rules ? config.nb_rules : fn;
592 : :
593 : : start = rte_rdtsc_precise();
594 : 0 : for (i = n; i != fn; i++) {
595 : 0 : ret = rte_ipsec_sad_del(sad,
596 : 0 : &rules_tbl[i].tuple,
597 : 0 : rules_tbl[i].rule_type);
598 : 0 : if (ret != 0 && ret != -ENOENT)
599 : 0 : rte_exit(ret, "%s failed @ %u-th rule\n",
600 : : __func__, i);
601 : : }
602 : 0 : tm[j] = rte_rdtsc_precise() - start;
603 : 0 : nm[j] = fn - n;
604 : : }
605 : :
606 : 0 : for (i = 0; i != j; i++)
607 : 0 : printf("DEL %u rules, %.2Lf cycles/rule, %.2Lf DEL/sec\n",
608 : : nm[i], (long double)tm[i] / nm[i],
609 : 0 : (long double)nm[i] * rte_get_tsc_hz() / tm[i]);
610 : 0 : }
611 : :
612 : : int
613 : 0 : main(int argc, char **argv)
614 : : {
615 : : int ret;
616 : : struct rte_ipsec_sad *sad;
617 : 0 : struct rte_ipsec_sad_conf conf = {0};
618 : : unsigned int lcore_id;
619 : :
620 : 0 : ret = rte_eal_init(argc, argv);
621 : 0 : if (ret < 0)
622 : 0 : rte_panic("Cannot init EAL\n");
623 : :
624 : 0 : argc -= ret;
625 : 0 : argv += ret;
626 : :
627 : 0 : config.prgname = argv[0];
628 : :
629 : 0 : parse_opts(argc, argv);
630 : 0 : tbl_init(&rules_tbl, &config.nb_rules, config.rules_file, 1);
631 : 0 : tbl_init(&tuples_tbl, &config.nb_tuples, config.tuples_file, 0);
632 : 0 : if (config.rules_file != NULL) {
633 : 0 : config.fract_32 = (100 * config.nb_rules_32) / config.nb_rules;
634 : 0 : config.fract_64 = (100 * config.nb_rules_64) / config.nb_rules;
635 : 0 : config.fract_96 = (100 * config.nb_rules_96) / config.nb_rules;
636 : : }
637 : 0 : if (config.tuples_file != NULL) {
638 : 0 : config.fract_rnd_tuples = 0;
639 : 0 : config.nb_tuples_rnd = 0;
640 : : }
641 : 0 : conf.socket_id = -1;
642 : 0 : conf.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = config.nb_rules_32 * 5 / 4;
643 : 0 : conf.max_sa[RTE_IPSEC_SAD_SPI_DIP] = config.nb_rules_64 * 5 / 4;
644 : 0 : conf.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = config.nb_rules_96 * 5 / 4;
645 : 0 : if (config.ipv6)
646 : 0 : conf.flags |= RTE_IPSEC_SAD_FLAG_IPV6;
647 : 0 : if (config.concurrent_rw)
648 : 0 : conf.flags |= RTE_IPSEC_SAD_FLAG_RW_CONCURRENCY;
649 : 0 : sad = rte_ipsec_sad_create("test", &conf);
650 : 0 : if (sad == NULL)
651 : 0 : rte_exit(-rte_errno, "can not allocate SAD table\n");
652 : :
653 : 0 : print_config();
654 : :
655 : 0 : add_rules(sad, 10);
656 : 0 : if (config.parallel_lookup)
657 : 0 : rte_eal_mp_remote_launch(lookup, sad, SKIP_MAIN);
658 : :
659 : 0 : lookup(sad);
660 : 0 : if (config.parallel_lookup)
661 : 0 : RTE_LCORE_FOREACH_WORKER(lcore_id)
662 : 0 : if (rte_eal_wait_lcore(lcore_id) < 0)
663 : : return -1;
664 : :
665 : 0 : del_rules(sad, 10);
666 : :
667 : 0 : return 0;
668 : : }
|