Add warning in case of wrong configuration (missing l3 submode)
[samplevnf.git] / VNFs / DPPD-PROX / stats_parser.c
1 /*
2 // Copyright (c) 2010-2017 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #include <string.h>
18 #include <stddef.h>
19
20 #include "stats_parser.h"
21 #include "log.h"
22 #include "stats.h"
23 #include "parse_utils.h"
24 #include "handle_lat.h"
25 #include "prox_port_cfg.h"
26 #include "stats_port.h"
27 #include "stats_mempool.h"
28 #include "stats_ring.h"
29 #include "stats_l4gen.h"
30 #include "stats_latency.h"
31 #include "stats_global.h"
32 #include "stats_prio_task.h"
33 #include "stats_irq.h"
34
35 struct stats_path_str {
36         const char *str;
37         uint64_t (*func)(int argc, const char *argv[]);
38 };
39
40 static int args_to_core_task(const char *core_str, const char *task_str, uint32_t *lcore_id, uint32_t *task_id)
41 {
42         if (parse_list_set(lcore_id, core_str, 1) != 1)
43                 return -1;
44         *task_id = atoi(task_str);
45
46         return 0;
47 }
48
49 static uint64_t sp_task_idle_cycles(int argc, const char *argv[])
50 {
51         struct task_stats_sample *last;
52         uint32_t c, t;
53
54         if (args_to_core_task(argv[0], argv[1], &c, &t))
55                 return -1;
56         return stats_get_task_stats_sample(c, t, 1)->tsc;
57 }
58
59 static uint64_t sp_task_rx_packets(int argc, const char *argv[])
60 {
61         struct task_stats_sample *last;
62         uint32_t c, t;
63
64         if (args_to_core_task(argv[0], argv[1], &c, &t))
65                 return -1;
66         return stats_get_task_stats_sample(c, t, 1)->rx_pkt_count;
67 }
68
69 static uint64_t sp_task_tx_packets(int argc, const char *argv[])
70 {
71         struct task_stats_sample *last;
72         uint32_t c, t;
73
74         if (args_to_core_task(argv[0], argv[1], &c, &t))
75                 return -1;
76         return stats_get_task_stats_sample(c, t, 1)->tx_pkt_count;
77 }
78
79 static uint64_t sp_task_drop_tx_fail(int argc, const char *argv[])
80 {
81         struct task_stats_sample *last;
82         uint32_t c, t;
83
84         if (args_to_core_task(argv[0], argv[1], &c, &t))
85                 return -1;
86         return stats_get_task_stats_sample(c, t, 1)->drop_tx_fail;
87 }
88
89 static uint64_t sp_task_drop_tx_fail_prio(int argc, const char *argv[])
90 {
91         struct task_stats_sample *last;
92         uint32_t c, t;
93
94         if (args_to_core_task(argv[0], argv[1], &c, &t))
95                 return -1;
96         if (stats_get_prio_task_stats_sample_by_core_task(c, t, 1))
97                 return stats_get_prio_task_stats_sample_by_core_task(c, t, 1)->drop_tx_fail_prio[atoi(argv[2])];
98         else
99                 return -1;
100 }
101
102 static uint64_t sp_task_rx_prio(int argc, const char *argv[])
103 {
104         struct task_stats_sample *last;
105         uint32_t c, t;
106
107         if (args_to_core_task(argv[0], argv[1], &c, &t))
108                 return -1;
109         return stats_get_prio_task_stats_sample_by_core_task(c, t, 1)->rx_prio[atoi(argv[2])];
110 }
111
112 static uint64_t sp_task_max_irq(int argc, const char *argv[])
113 {
114         struct task_stats_sample *last;
115         uint32_t c, t;
116
117         if (args_to_core_task(argv[0], argv[1], &c, &t))
118                 return -1;
119         return get_max_irq_stats_by_core_task(c, t);
120 }
121
122 static uint64_t sp_task_irq(int argc, const char *argv[])
123 {
124         struct task_stats_sample *last;
125         uint32_t c, t;
126
127         if (args_to_core_task(argv[0], argv[1], &c, &t))
128                 return -1;
129         return get_irq_stats_by_core_task(c, t, atoi(argv[2]));
130 }
131
132 static uint64_t sp_task_drop_discard(int argc, const char *argv[])
133 {
134         struct task_stats_sample *last;
135         uint32_t c, t;
136
137         if (args_to_core_task(argv[0], argv[1], &c, &t))
138                 return -1;
139         return stats_get_task_stats_sample(c, t, 1)->drop_discard;
140 }
141
142 static uint64_t sp_task_drop_handled(int argc, const char *argv[])
143 {
144         struct task_stats_sample *last;
145         uint32_t c, t;
146
147         if (args_to_core_task(argv[0], argv[1], &c, &t))
148                 return -1;
149         return stats_get_task_stats_sample(c, t, 1)->drop_handled;
150 }
151
152 static uint64_t sp_task_rx_non_dp(int argc, const char *argv[])
153 {
154         struct task_stats_sample *last;
155         uint32_t c, t;
156         if (args_to_core_task(argv[0], argv[1], &c, &t))
157                 return -1;
158         return stats_get_task_stats_sample(c, t, 1)->rx_non_dp;
159 }
160
161 static uint64_t sp_task_tx_non_dp(int argc, const char *argv[])
162 {
163         struct task_stats_sample *last;
164         uint32_t c, t;
165         if (args_to_core_task(argv[0], argv[1], &c, &t))
166                 return -1;
167         return stats_get_task_stats_sample(c, t, 1)->tx_non_dp;
168 }
169 static uint64_t sp_task_rx_bytes(int argc, const char *argv[])
170 {
171         return -1;
172 }
173
174 static uint64_t sp_task_tx_bytes(int argc, const char *argv[])
175 {
176         return -1;
177 }
178
179 static uint64_t sp_task_tsc(int argc, const char *argv[])
180 {
181         struct task_stats_sample *last;
182         uint32_t c, t;
183
184         if (args_to_core_task(argv[0], argv[1], &c, &t))
185                 return -1;
186         return stats_get_task_stats_sample(c, t, 1)->tsc;
187 }
188
189 static uint64_t sp_l4gen_created(int argc, const char *argv[])
190 {
191         struct l4_stats_sample *clast = NULL;
192
193         if (atoi(argv[0]) >= stats_get_n_l4gen())
194                 return -1;
195         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
196         return clast->stats.tcp_created + clast->stats.udp_created;
197 }
198
199 static uint64_t sp_l4gen_finished(int argc, const char *argv[])
200 {
201         struct l4_stats_sample *clast = NULL;
202
203         if (atoi(argv[0]) >= stats_get_n_l4gen())
204                 return -1;
205         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
206         return clast->stats.tcp_finished_retransmit + clast->stats.tcp_finished_no_retransmit +
207                 clast->stats.udp_finished + clast->stats.udp_expired + clast->stats.tcp_expired;
208 }
209
210 static uint64_t sp_l4gen_expire_tcp(int argc, const char *argv[])
211 {
212         struct l4_stats_sample *clast = NULL;
213
214         if (atoi(argv[0]) >= stats_get_n_l4gen())
215                 return -1;
216         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
217         return  clast->stats.tcp_expired;
218 }
219
220 static uint64_t sp_l4gen_expire_udp(int argc, const char *argv[])
221 {
222         struct l4_stats_sample *clast = NULL;
223
224         if (atoi(argv[0]) >= stats_get_n_l4gen())
225                 return -1;
226         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
227         return clast->stats.udp_expired;
228 }
229
230 static uint64_t sp_l4gen_retx(int argc, const char *argv[])
231 {
232         struct l4_stats_sample *clast = NULL;
233
234         if (atoi(argv[0]) >= stats_get_n_l4gen())
235                 return -1;
236         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
237         return clast->stats.tcp_retransmits;
238 }
239
240 static uint64_t sp_l4gen_tsc(int argc, const char *argv[])
241 {
242         struct l4_stats_sample *clast = NULL;
243
244         if (atoi(argv[0]) >= stats_get_n_l4gen())
245                 return -1;
246         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
247         return clast->tsc;
248 }
249
250 static uint64_t sp_l4gen_torndown_no_retx(int argc, const char *argv[])
251 {
252         struct l4_stats_sample *clast = NULL;
253
254         if (atoi(argv[0]) >= stats_get_n_l4gen())
255                 return -1;
256         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
257         return clast->stats.tcp_finished_no_retransmit;
258 }
259
260 static uint64_t sp_l4gen_torndown_retx(int argc, const char *argv[])
261 {
262         struct l4_stats_sample *clast = NULL;
263
264         if (atoi(argv[0]) >= stats_get_n_l4gen())
265                 return -1;
266         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
267         return clast->stats.tcp_finished_retransmit;
268 }
269
270 static uint64_t sp_l4gen_torndown_udp(int argc, const char *argv[])
271 {
272         struct l4_stats_sample *clast = NULL;
273
274         if (atoi(argv[0]) >= stats_get_n_l4gen())
275                 return -1;
276         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
277         return clast->stats.udp_finished;
278 }
279
280 static uint64_t sp_l4gen_created_tcp(int argc, const char *argv[])
281 {
282         struct l4_stats_sample *clast = NULL;
283
284         if (atoi(argv[0]) >= stats_get_n_l4gen())
285                 return -1;
286         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
287         return clast->stats.tcp_created;
288
289 }
290
291 static uint64_t sp_l4gen_created_udp(int argc, const char *argv[])
292 {
293         struct l4_stats_sample *clast = NULL;
294
295         if (atoi(argv[0]) >= stats_get_n_l4gen())
296                 return -1;
297         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
298         return clast->stats.udp_created;
299 }
300
301 static uint64_t sp_l4gen_created_all(int argc, const char *argv[])
302 {
303         struct l4_stats_sample *clast = NULL;
304
305         if (atoi(argv[0]) >= stats_get_n_l4gen())
306                 return -1;
307         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
308         return clast->stats.tcp_created + clast->stats.udp_created;
309 }
310
311 static uint64_t sp_l4gen_created_bundles(int argc, const char *argv[])
312 {
313         struct l4_stats_sample *clast = NULL;
314
315         if (atoi(argv[0]) >= stats_get_n_l4gen())
316                 return -1;
317         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
318         return clast->stats.bundles_created;
319 }
320
321 static uint64_t sp_latency_min(int argc, const char *argv[])
322 {
323         struct stats_latency *lat_test = NULL;
324
325         if (atoi(argv[0]) >= stats_get_n_latency())
326                 return -1;
327         lat_test = stats_latency_get(atoi(argv[0]));
328
329         if (!lat_test->tot_packets)
330                 return -1;
331
332         struct time_unit tu = lat_test->min.time;
333         return time_unit_to_usec(&tu);
334 }
335
336 static uint64_t sp_mem_used(int argc, const char *argv[])
337 {
338         struct mempool_stats *ms;
339
340         if (atoi(argv[0]) > stats_get_n_mempools())
341                 return -1;
342         ms = stats_get_mempool_stats(atoi(argv[0]));
343         return ms->size - ms->free;
344 }
345
346 static uint64_t sp_mem_free(int argc, const char *argv[])
347 {
348         struct mempool_stats *ms;
349
350         if (atoi(argv[0]) > stats_get_n_mempools())
351                 return -1;
352         ms = stats_get_mempool_stats(atoi(argv[0]));
353         return ms->free;
354 }
355
356 static uint64_t sp_mem_size(int argc, const char *argv[])
357 {
358         struct mempool_stats *ms;
359
360         if (atoi(argv[0]) > stats_get_n_mempools())
361                 return -1;
362         ms = stats_get_mempool_stats(atoi(argv[0]));
363         return ms->size;
364 }
365
366 static uint64_t sp_port_no_mbufs(int argc, const char *argv[])
367 {
368         uint32_t port_id = atoi(argv[0]);
369         struct port_stats_sample *ps;
370
371         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
372                 return -1;
373         ps = stats_get_port_stats_sample(port_id, 1);
374         return ps->no_mbufs;
375 }
376
377 static uint64_t sp_port_ierrors(int argc, const char *argv[])
378 {
379         uint32_t port_id = atoi(argv[0]);
380         struct port_stats_sample *ps;
381
382         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
383                 return -1;
384         ps = stats_get_port_stats_sample(port_id, 1);
385         return ps->ierrors;
386 }
387
388 static uint64_t sp_port_imissed(int argc, const char *argv[])
389 {
390         uint32_t port_id = atoi(argv[0]);
391         struct port_stats_sample *ps;
392
393         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
394                 return -1;
395         ps = stats_get_port_stats_sample(port_id, 1);
396         return ps->imissed;
397 }
398
399 static uint64_t sp_port_oerrors(int argc, const char *argv[])
400 {
401         uint32_t port_id = atoi(argv[0]);
402         struct port_stats_sample *ps;
403
404         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
405                 return -1;
406         ps = stats_get_port_stats_sample(port_id, 1);
407         return ps->oerrors;
408 }
409
410 static uint64_t sp_port_rx_packets(int argc, const char *argv[])
411 {
412         uint32_t port_id = atoi(argv[0]);
413         struct port_stats_sample *ps;
414
415         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
416                 return -1;
417         ps = stats_get_port_stats_sample(port_id, 1);
418         return ps->rx_tot;
419 }
420
421 static uint64_t sp_port_tx_packets(int argc, const char *argv[])
422 {
423         uint32_t port_id = atoi(argv[0]);
424         struct port_stats_sample *ps;
425
426         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
427                 return -1;
428         ps = stats_get_port_stats_sample(port_id, 1);
429         return ps->tx_tot;
430 }
431
432 static uint64_t sp_port_rx_bytes(int argc, const char *argv[])
433 {
434         uint32_t port_id = atoi(argv[0]);
435         struct port_stats_sample *ps;
436
437         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
438                 return -1;
439         ps = stats_get_port_stats_sample(port_id, 1);
440         return ps->rx_bytes;
441 }
442
443 static uint64_t sp_port_tx_bytes(int argc, const char *argv[])
444 {
445         uint32_t port_id = atoi(argv[0]);
446         struct port_stats_sample *ps;
447
448         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
449                 return -1;
450         ps = stats_get_port_stats_sample(port_id, 1);
451         return ps->tx_bytes;
452 }
453
454 static uint64_t sp_port_tx_packets_64(int argc, const char *argv[])
455 {
456         uint32_t port_id = atoi(argv[0]);
457         struct port_stats_sample *ps;
458
459         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
460                 return -1;
461         ps = stats_get_port_stats_sample(port_id, 1);
462         return ps->tx_pkt_size[PKT_SIZE_64];
463 }
464
465 static uint64_t sp_port_tx_packets_65_127(int argc, const char *argv[])
466 {
467         uint32_t port_id = atoi(argv[0]);
468         struct port_stats_sample *ps;
469
470         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
471                 return -1;
472         ps = stats_get_port_stats_sample(port_id, 1);
473         return ps->tx_pkt_size[PKT_SIZE_65];
474 }
475
476 static uint64_t sp_port_tx_packets_128_255(int argc, const char *argv[])
477 {
478         uint32_t port_id = atoi(argv[0]);
479         struct port_stats_sample *ps;
480
481         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
482                 return -1;
483         ps = stats_get_port_stats_sample(port_id, 1);
484         return ps->tx_pkt_size[PKT_SIZE_128];
485 }
486
487 static uint64_t sp_port_tx_packets_256_511(int argc, const char *argv[])
488 {
489         uint32_t port_id = atoi(argv[0]);
490         struct port_stats_sample *ps;
491
492         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
493                 return -1;
494         ps = stats_get_port_stats_sample(port_id, 1);
495         return ps->tx_pkt_size[PKT_SIZE_256];
496 }
497
498 static uint64_t sp_port_tx_packets_512_1023(int argc, const char *argv[])
499 {
500         uint32_t port_id = atoi(argv[0]);
501         struct port_stats_sample *ps;
502
503         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
504                 return -1;
505         ps = stats_get_port_stats_sample(port_id, 1);
506         return ps->tx_pkt_size[PKT_SIZE_512];
507 }
508
509 static uint64_t sp_port_tx_packets_1024_1522(int argc, const char *argv[])
510 {
511         uint32_t port_id = atoi(argv[0]);
512         struct port_stats_sample *ps;
513
514         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
515                 return -1;
516         ps = stats_get_port_stats_sample(port_id, 1);
517         return ps->tx_pkt_size[PKT_SIZE_1024];
518 }
519
520 static uint64_t sp_port_tx_packets_1523_max(int argc, const char *argv[])
521 {
522         uint32_t port_id = atoi(argv[0]);
523         struct port_stats_sample *ps;
524
525         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
526                 return -1;
527         ps = stats_get_port_stats_sample(port_id, 1);
528         return ps->tx_pkt_size[PKT_SIZE_1522];
529 }
530
531 static uint64_t sp_port_tsc(int argc, const char *argv[])
532 {
533         uint32_t port_id = atoi(argv[0]);
534         struct port_stats_sample *ps;
535
536         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
537                 return -1;
538         ps = stats_get_port_stats_sample(port_id, 1);
539         return ps->tsc;
540 }
541
542 static uint64_t sp_latency_max(int argc, const char *argv[])
543 {
544         struct stats_latency *lat_test = NULL;
545
546         if (atoi(argv[0]) >= stats_get_n_latency())
547                 return -1;
548         lat_test = stats_latency_get(atoi(argv[0]));
549
550         if (!lat_test->tot_packets)
551                 return -1;
552
553         struct time_unit tu = lat_test->max.time;
554         return time_unit_to_usec(&tu);
555 }
556
557 static uint64_t sp_latency_avg(int argc, const char *argv[])
558 {
559         struct stats_latency *lat_test = NULL;
560
561         if (atoi(argv[0]) >= stats_get_n_latency())
562                 return -1;
563         lat_test = stats_latency_get(atoi(argv[0]));
564
565         if (!lat_test->tot_packets)
566                 return -1;
567
568         struct time_unit tu = lat_test->avg.time;
569         return time_unit_to_usec(&tu);
570 }
571
572 static uint64_t sp_latency_lost(int argc, const char *argv[])
573 {
574         struct stats_latency *lat_test = NULL;
575
576         if (atoi(argv[0]) >= stats_get_n_latency())
577                 return -1;
578         lat_test = stats_latency_get(atoi(argv[0]));
579
580         if (!lat_test->tot_packets)
581                 return -1;
582
583         return lat_test->lost_packets;
584 }
585
586 static uint64_t sp_latency_tot_lost(int argc, const char *argv[])
587 {
588         struct stats_latency *lat_test = NULL;
589
590         if (atoi(argv[0]) >= stats_get_n_latency())
591                 return -1;
592         lat_test = stats_latency_tot_get(atoi(argv[0]));
593
594         if (!lat_test->tot_packets)
595                 return -1;
596
597         return lat_test->lost_packets;
598 }
599
600 static uint64_t sp_latency_total(int argc, const char *argv[])
601 {
602         struct stats_latency *lat_test = NULL;
603
604         if (atoi(argv[0]) >= stats_get_n_latency())
605                 return -1;
606         lat_test = stats_latency_get(atoi(argv[0]));
607
608         if (!lat_test->tot_all_packets)
609                 return -1;
610
611         return lat_test->tot_all_packets;
612 }
613
614 static uint64_t sp_latency_used(int argc, const char *argv[])
615 {
616         struct stats_latency *lat_test = NULL;
617
618         if (atoi(argv[0]) >= stats_get_n_latency())
619                 return -1;
620         lat_test = stats_latency_get(atoi(argv[0]));
621
622         if (!lat_test->tot_all_packets)
623                 return -1;
624
625         return lat_test->tot_packets;
626 }
627
628 static uint64_t sp_latency_tot_total(int argc, const char *argv[])
629 {
630         struct stats_latency *lat_test = NULL;
631
632         if (atoi(argv[0]) >= stats_get_n_latency())
633                 return -1;
634         lat_test = stats_latency_tot_get(atoi(argv[0]));
635
636         if (!lat_test->tot_all_packets)
637                 return -1;
638
639         return lat_test->tot_all_packets;
640 }
641
642 static uint64_t sp_latency_tot_used(int argc, const char *argv[])
643 {
644         struct stats_latency *lat_test = NULL;
645
646         if (atoi(argv[0]) >= stats_get_n_latency())
647                 return -1;
648         lat_test = stats_latency_tot_get(atoi(argv[0]));
649
650         if (!lat_test->tot_all_packets)
651                 return -1;
652
653         return lat_test->tot_packets;
654 }
655
656 static uint64_t sp_latency_tot_min(int argc, const char *argv[])
657 {
658         struct stats_latency *lat_test = NULL;
659
660         if (atoi(argv[0]) >= stats_get_n_latency())
661                 return -1;
662         lat_test = stats_latency_tot_get(atoi(argv[0]));
663
664         if (!lat_test->tot_packets)
665                 return -1;
666
667         struct time_unit tu = lat_test->min.time;
668         return time_unit_to_usec(&tu);
669 }
670
671 static uint64_t sp_latency_tot_max(int argc, const char *argv[])
672 {
673         struct stats_latency *lat_test = NULL;
674
675         if (atoi(argv[0]) >= stats_get_n_latency())
676                 return -1;
677         lat_test = stats_latency_tot_get(atoi(argv[0]));
678
679         if (!lat_test->tot_packets)
680                 return -1;
681
682         struct time_unit tu = lat_test->max.time;
683         return time_unit_to_usec(&tu);
684 }
685
686 static uint64_t sp_latency_tot_avg(int argc, const char *argv[])
687 {
688         struct stats_latency *lat_test = NULL;
689
690         if (atoi(argv[0]) >= stats_get_n_latency())
691                 return -1;
692         lat_test = stats_latency_tot_get(atoi(argv[0]));
693
694         if (!lat_test->tot_packets)
695                 return -1;
696
697         struct time_unit tu = lat_test->avg.time;
698         return time_unit_to_usec(&tu);
699 }
700
701 static uint64_t sp_latency_stddev(int argc, const char *argv[])
702 {
703         struct stats_latency *lat_test = NULL;
704
705         if (atoi(argv[0]) >= stats_get_n_latency())
706                 return -1;
707         lat_test = stats_latency_get(atoi(argv[0]));
708
709         if (!lat_test->tot_packets)
710                 return -1;
711
712         struct time_unit tu = lat_test->stddev.time;
713         return time_unit_to_usec(&tu);
714 }
715
716 static uint64_t sp_ring_used(int argc, const char *argv[])
717 {
718         struct ring_stats *rs = NULL;
719
720         if (atoi(argv[0]) >= stats_get_n_rings())
721                 return -1;
722         rs = stats_get_ring_stats(atoi(argv[0]));
723         return rs->size - rs->free;
724 }
725
726 static uint64_t sp_ring_free(int argc, const char *argv[])
727 {
728         struct ring_stats *rs = NULL;
729
730         if (atoi(argv[0]) >= stats_get_n_rings())
731                 return -1;
732         rs = stats_get_ring_stats(atoi(argv[0]));
733         return rs->free;
734 }
735
736 static uint64_t sp_ring_size(int argc, const char *argv[])
737 {
738         struct ring_stats *rs = NULL;
739
740         if (atoi(argv[0]) >= stats_get_n_rings())
741                 return -1;
742         rs = stats_get_ring_stats(atoi(argv[0]));
743         return rs->size;
744 }
745
746 static uint64_t sp_global_host_rx_packets(int argc, const char *argv[])
747 {
748         return stats_get_global_stats(1)->host_rx_packets;
749 }
750
751 static uint64_t sp_global_host_tx_packets(int argc, const char *argv[])
752 {
753         return stats_get_global_stats(1)->host_tx_packets;
754 }
755
756 static uint64_t sp_global_nics_rx_packets(int argc, const char *argv[])
757 {
758         return stats_get_global_stats(1)->nics_rx_packets;
759 }
760
761 static uint64_t sp_global_nics_tx_packets(int argc, const char *argv[])
762 {
763         return stats_get_global_stats(1)->nics_tx_packets;
764 }
765
766 static uint64_t sp_global_nics_ierrors(int argc, const char *argv[])
767 {
768         return stats_get_global_stats(1)->nics_ierrors;
769 }
770
771 static uint64_t sp_global_nics_imissed(int argc, const char *argv[])
772 {
773         return stats_get_global_stats(1)->nics_imissed;
774 }
775
776 static uint64_t sp_global_tsc(int argc, const char *argv[])
777 {
778         return stats_get_global_stats(1)->tsc;
779 }
780
781 static uint64_t sp_hz(int argc, const char *argv[])
782 {
783         return rte_get_tsc_hz();
784 }
785
786 struct stats_path_str stats_paths[] = {
787         {"hz", sp_hz},
788
789         {"global.host.rx.packets", sp_global_host_rx_packets},
790         {"global.host.tx.packets", sp_global_host_tx_packets},
791         {"global.nics.rx.packets", sp_global_nics_rx_packets},
792         {"global.nics.tx.packets", sp_global_nics_tx_packets},
793         {"global.nics.ierrrors", sp_global_nics_ierrors},
794         {"global.nics.imissed", sp_global_nics_imissed},
795         {"global.tsc", sp_global_tsc},
796
797         {"task.core(#).task(#).idle_cycles", sp_task_idle_cycles},
798         {"task.core(#).task(#).rx.packets", sp_task_rx_packets},
799         {"task.core(#).task(#).tx.packets", sp_task_tx_packets},
800         {"task.core(#).task(#).drop.tx_fail", sp_task_drop_tx_fail},
801         {"task.core(#).task(#).drop.discard", sp_task_drop_discard},
802         {"task.core(#).task(#).drop.handled", sp_task_drop_handled},
803         {"task.core(#).task(#).rx.bytes", sp_task_rx_bytes},
804         {"task.core(#).task(#).tx.bytes", sp_task_tx_bytes},
805         {"task.core(#).task(#).tsc", sp_task_tsc},
806         {"task.core(#).task(#).drop.tx_fail_prio(#)", sp_task_drop_tx_fail_prio},
807         {"task.core(#).task(#).rx_prio(#)", sp_task_rx_prio},
808         {"task.core(#).task(#).max_irq", sp_task_max_irq},
809         {"task.core(#).task(#).irq(#)", sp_task_irq},
810         {"task.core(#).task(#).rx_non_dp", sp_task_rx_non_dp},
811         {"task.core(#).task(#).tx_non_dp", sp_task_tx_non_dp},
812
813         {"port(#).no_mbufs", sp_port_no_mbufs},
814         {"port(#).ierrors", sp_port_ierrors},
815         {"port(#).imissed", sp_port_imissed},
816         {"port(#).oerrors", sp_port_oerrors},
817         {"port(#).rx.packets", sp_port_rx_packets},
818         {"port(#).tx.packets", sp_port_tx_packets},
819         {"port(#).rx.bytes", sp_port_rx_bytes},
820         {"port(#).tx.bytes", sp_port_tx_bytes},
821         {"port(#).tx.packets_64", sp_port_tx_packets_64},
822         {"port(#).tx.packets_65_127", sp_port_tx_packets_65_127},
823         {"port(#).tx.packets_128_255", sp_port_tx_packets_128_255},
824         {"port(#).tx.packets_256_511", sp_port_tx_packets_256_511},
825         {"port(#).tx.packets_512_1023", sp_port_tx_packets_512_1023},
826         {"port(#).tx.packets_1024_1522", sp_port_tx_packets_1024_1522},
827         {"port(#).tx.packets_1523_max", sp_port_tx_packets_1523_max},
828         {"port(#).tsc", sp_port_tsc},
829
830         {"mem(#).used", sp_mem_used},
831         {"mem(#).free", sp_mem_free},
832         {"mem(#).size", sp_mem_size},
833
834         {"latency(#).min", sp_latency_min},
835         {"latency(#).max", sp_latency_max},
836         {"latency(#).avg", sp_latency_avg},
837         {"latency(#).lost", sp_latency_lost},
838         {"latency(#).used", sp_latency_used},
839         {"latency(#).total", sp_latency_total},
840         {"latency(#).tot.min", sp_latency_tot_min},
841         {"latency(#).tot.max", sp_latency_tot_max},
842         {"latency(#).tot.avg", sp_latency_tot_avg},
843         {"latency(#).tot.lost", sp_latency_tot_lost},
844         {"latency(#).tot.used", sp_latency_tot_used},
845         {"latency(#).tot.total", sp_latency_tot_total},
846         {"latency(#).stddev", sp_latency_stddev},
847
848         {"ring(#).used", sp_ring_used},
849         {"ring(#).free", sp_ring_free},
850         {"ring(#).size", sp_ring_size},
851
852         {"l4gen(#).created.tcp", sp_l4gen_created_tcp},
853         {"l4gen(#).created.udp", sp_l4gen_created_udp},
854         {"l4gen(#).created.all", sp_l4gen_created_all},
855         {"l4gen(#).created.bundles", sp_l4gen_created_bundles},
856         {"l4gen(#).torndown.no_retx", sp_l4gen_torndown_no_retx},
857         {"l4gen(#).torndown.retx", sp_l4gen_torndown_retx},
858         {"l4gen(#).torndown.udp", sp_l4gen_torndown_udp},
859         {"l4gen(#).expired.tcp", sp_l4gen_expire_tcp},
860         {"l4gen(#).expired.udp", sp_l4gen_expire_udp},
861         {"l4gen(#).created", sp_l4gen_created},
862         {"l4gen(#).finished", sp_l4gen_finished},
863         {"l4gen(#).retx", sp_l4gen_retx},
864         {"l4gen(#).tsc", sp_l4gen_tsc},
865 };
866
867 static int stats_parser_extract_args(char *stats_path, size_t *argc, char **argv)
868 {
869         size_t len = strlen(stats_path);
870         size_t j = 0;
871         size_t k = 0;
872         int state = 0;
873
874         for (size_t i = 0; i < len; ++i) {
875                 switch (state) {
876                 case 0:
877                         if (stats_path[i] == '(') {
878                                 state = 1;
879                                 k = 0;
880                         }
881                         else if (stats_path[i] == ')')
882                                 return -1;
883                         stats_path[j] = stats_path[i];
884                         j++;
885                         break;
886                 case 1:
887                         if (stats_path[i] == ')') {
888                                 state = 0;
889                                 stats_path[j] = '#';
890                                 j++;
891                                 stats_path[j] = ')';
892                                 j++;
893                                 (*argc)++;
894                         }
895                         else {
896                                 argv[*argc][k++] = stats_path[i];
897                         }
898                         break;
899                 }
900         }
901         if (state == 1)
902                 return -1;
903         stats_path[j] = 0;
904         return 0;
905 }
906
907 uint64_t stats_parser_get(const char *stats_path)
908 {
909         size_t stats_path_len;
910
911         char stats_path_cpy[128];
912
913         strncpy(stats_path_cpy, stats_path, sizeof(stats_path_cpy));
914         stats_path_len = strlen(stats_path);
915
916         size_t max_argc = 16;
917         size_t argc = 0;
918         char argv_data[16][16] = {{0}};
919         char *argv[16];
920         const char *argv_c[16];
921
922         for (size_t i = 0; i < 16; ++i) {
923                 argv[i] = argv_data[i];
924                 argv_c[i] = argv_data[i];
925         }
926
927         if (stats_parser_extract_args(stats_path_cpy, &argc, argv))
928                 return -1;
929
930         for (size_t i = 0; i < sizeof(stats_paths)/sizeof(stats_paths[0]); ++i) {
931                 if (strcmp(stats_paths[i].str, stats_path_cpy) == 0) {
932                         if (stats_paths[i].func == NULL)
933                                 return -1;
934                         return stats_paths[i].func(argc, argv_c);
935                 }
936         }
937
938         return -1;
939 }