Integrate irq mode into PROX (support display and command line)
[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_bytes(int argc, const char *argv[])
153 {
154         return -1;
155 }
156
157 static uint64_t sp_task_tx_bytes(int argc, const char *argv[])
158 {
159         return -1;
160 }
161
162 static uint64_t sp_task_tsc(int argc, const char *argv[])
163 {
164         struct task_stats_sample *last;
165         uint32_t c, t;
166
167         if (args_to_core_task(argv[0], argv[1], &c, &t))
168                 return -1;
169         return stats_get_task_stats_sample(c, t, 1)->tsc;
170 }
171
172 static uint64_t sp_l4gen_created(int argc, const char *argv[])
173 {
174         struct l4_stats_sample *clast = NULL;
175
176         if (atoi(argv[0]) >= stats_get_n_l4gen())
177                 return -1;
178         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
179         return clast->stats.tcp_created + clast->stats.udp_created;
180 }
181
182 static uint64_t sp_l4gen_finished(int argc, const char *argv[])
183 {
184         struct l4_stats_sample *clast = NULL;
185
186         if (atoi(argv[0]) >= stats_get_n_l4gen())
187                 return -1;
188         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
189         return clast->stats.tcp_finished_retransmit + clast->stats.tcp_finished_no_retransmit +
190                 clast->stats.udp_finished + clast->stats.udp_expired + clast->stats.tcp_expired;
191 }
192
193 static uint64_t sp_l4gen_expire_tcp(int argc, const char *argv[])
194 {
195         struct l4_stats_sample *clast = NULL;
196
197         if (atoi(argv[0]) >= stats_get_n_l4gen())
198                 return -1;
199         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
200         return  clast->stats.tcp_expired;
201 }
202
203 static uint64_t sp_l4gen_expire_udp(int argc, const char *argv[])
204 {
205         struct l4_stats_sample *clast = NULL;
206
207         if (atoi(argv[0]) >= stats_get_n_l4gen())
208                 return -1;
209         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
210         return clast->stats.udp_expired;
211 }
212
213 static uint64_t sp_l4gen_retx(int argc, const char *argv[])
214 {
215         struct l4_stats_sample *clast = NULL;
216
217         if (atoi(argv[0]) >= stats_get_n_l4gen())
218                 return -1;
219         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
220         return clast->stats.tcp_retransmits;
221 }
222
223 static uint64_t sp_l4gen_tsc(int argc, const char *argv[])
224 {
225         struct l4_stats_sample *clast = NULL;
226
227         if (atoi(argv[0]) >= stats_get_n_l4gen())
228                 return -1;
229         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
230         return clast->tsc;
231 }
232
233 static uint64_t sp_l4gen_torndown_no_retx(int argc, const char *argv[])
234 {
235         struct l4_stats_sample *clast = NULL;
236
237         if (atoi(argv[0]) >= stats_get_n_l4gen())
238                 return -1;
239         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
240         return clast->stats.tcp_finished_no_retransmit;
241 }
242
243 static uint64_t sp_l4gen_torndown_retx(int argc, const char *argv[])
244 {
245         struct l4_stats_sample *clast = NULL;
246
247         if (atoi(argv[0]) >= stats_get_n_l4gen())
248                 return -1;
249         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
250         return clast->stats.tcp_finished_retransmit;
251 }
252
253 static uint64_t sp_l4gen_torndown_udp(int argc, const char *argv[])
254 {
255         struct l4_stats_sample *clast = NULL;
256
257         if (atoi(argv[0]) >= stats_get_n_l4gen())
258                 return -1;
259         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
260         return clast->stats.udp_finished;
261 }
262
263 static uint64_t sp_l4gen_created_tcp(int argc, const char *argv[])
264 {
265         struct l4_stats_sample *clast = NULL;
266
267         if (atoi(argv[0]) >= stats_get_n_l4gen())
268                 return -1;
269         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
270         return clast->stats.tcp_created;
271
272 }
273
274 static uint64_t sp_l4gen_created_udp(int argc, const char *argv[])
275 {
276         struct l4_stats_sample *clast = NULL;
277
278         if (atoi(argv[0]) >= stats_get_n_l4gen())
279                 return -1;
280         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
281         return clast->stats.udp_created;
282 }
283
284 static uint64_t sp_l4gen_created_all(int argc, const char *argv[])
285 {
286         struct l4_stats_sample *clast = NULL;
287
288         if (atoi(argv[0]) >= stats_get_n_l4gen())
289                 return -1;
290         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
291         return clast->stats.tcp_created + clast->stats.udp_created;
292 }
293
294 static uint64_t sp_l4gen_created_bundles(int argc, const char *argv[])
295 {
296         struct l4_stats_sample *clast = NULL;
297
298         if (atoi(argv[0]) >= stats_get_n_l4gen())
299                 return -1;
300         clast = stats_get_l4_stats_sample(atoi(argv[0]), 1);
301         return clast->stats.bundles_created;
302 }
303
304 static uint64_t sp_latency_min(int argc, const char *argv[])
305 {
306         struct stats_latency *lat_test = NULL;
307
308         if (atoi(argv[0]) >= stats_get_n_latency())
309                 return -1;
310         lat_test = stats_latency_get(atoi(argv[0]));
311
312         if (!lat_test->tot_packets)
313                 return -1;
314
315         struct time_unit tu = lat_test->min.time;
316         return time_unit_to_usec(&tu);
317 }
318
319 static uint64_t sp_mem_used(int argc, const char *argv[])
320 {
321         struct mempool_stats *ms;
322
323         if (atoi(argv[0]) > stats_get_n_mempools())
324                 return -1;
325         ms = stats_get_mempool_stats(atoi(argv[0]));
326         return ms->size - ms->free;
327 }
328
329 static uint64_t sp_mem_free(int argc, const char *argv[])
330 {
331         struct mempool_stats *ms;
332
333         if (atoi(argv[0]) > stats_get_n_mempools())
334                 return -1;
335         ms = stats_get_mempool_stats(atoi(argv[0]));
336         return ms->free;
337 }
338
339 static uint64_t sp_mem_size(int argc, const char *argv[])
340 {
341         struct mempool_stats *ms;
342
343         if (atoi(argv[0]) > stats_get_n_mempools())
344                 return -1;
345         ms = stats_get_mempool_stats(atoi(argv[0]));
346         return ms->size;
347 }
348
349 static uint64_t sp_port_no_mbufs(int argc, const char *argv[])
350 {
351         uint32_t port_id = atoi(argv[0]);
352         struct port_stats_sample *ps;
353
354         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
355                 return -1;
356         ps = stats_get_port_stats_sample(port_id, 1);
357         return ps->no_mbufs;
358 }
359
360 static uint64_t sp_port_ierrors(int argc, const char *argv[])
361 {
362         uint32_t port_id = atoi(argv[0]);
363         struct port_stats_sample *ps;
364
365         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
366                 return -1;
367         ps = stats_get_port_stats_sample(port_id, 1);
368         return ps->ierrors;
369 }
370
371 static uint64_t sp_port_imissed(int argc, const char *argv[])
372 {
373         uint32_t port_id = atoi(argv[0]);
374         struct port_stats_sample *ps;
375
376         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
377                 return -1;
378         ps = stats_get_port_stats_sample(port_id, 1);
379         return ps->imissed;
380 }
381
382 static uint64_t sp_port_oerrors(int argc, const char *argv[])
383 {
384         uint32_t port_id = atoi(argv[0]);
385         struct port_stats_sample *ps;
386
387         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
388                 return -1;
389         ps = stats_get_port_stats_sample(port_id, 1);
390         return ps->oerrors;
391 }
392
393 static uint64_t sp_port_rx_packets(int argc, const char *argv[])
394 {
395         uint32_t port_id = atoi(argv[0]);
396         struct port_stats_sample *ps;
397
398         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
399                 return -1;
400         ps = stats_get_port_stats_sample(port_id, 1);
401         return ps->rx_tot;
402 }
403
404 static uint64_t sp_port_tx_packets(int argc, const char *argv[])
405 {
406         uint32_t port_id = atoi(argv[0]);
407         struct port_stats_sample *ps;
408
409         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
410                 return -1;
411         ps = stats_get_port_stats_sample(port_id, 1);
412         return ps->tx_tot;
413 }
414
415 static uint64_t sp_port_rx_bytes(int argc, const char *argv[])
416 {
417         uint32_t port_id = atoi(argv[0]);
418         struct port_stats_sample *ps;
419
420         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
421                 return -1;
422         ps = stats_get_port_stats_sample(port_id, 1);
423         return ps->rx_bytes;
424 }
425
426 static uint64_t sp_port_tx_bytes(int argc, const char *argv[])
427 {
428         uint32_t port_id = atoi(argv[0]);
429         struct port_stats_sample *ps;
430
431         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
432                 return -1;
433         ps = stats_get_port_stats_sample(port_id, 1);
434         return ps->tx_bytes;
435 }
436
437 static uint64_t sp_port_tx_packets_64(int argc, const char *argv[])
438 {
439         uint32_t port_id = atoi(argv[0]);
440         struct port_stats_sample *ps;
441
442         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
443                 return -1;
444         ps = stats_get_port_stats_sample(port_id, 1);
445         return ps->tx_pkt_size[PKT_SIZE_64];
446 }
447
448 static uint64_t sp_port_tx_packets_65_127(int argc, const char *argv[])
449 {
450         uint32_t port_id = atoi(argv[0]);
451         struct port_stats_sample *ps;
452
453         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
454                 return -1;
455         ps = stats_get_port_stats_sample(port_id, 1);
456         return ps->tx_pkt_size[PKT_SIZE_65];
457 }
458
459 static uint64_t sp_port_tx_packets_128_255(int argc, const char *argv[])
460 {
461         uint32_t port_id = atoi(argv[0]);
462         struct port_stats_sample *ps;
463
464         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
465                 return -1;
466         ps = stats_get_port_stats_sample(port_id, 1);
467         return ps->tx_pkt_size[PKT_SIZE_128];
468 }
469
470 static uint64_t sp_port_tx_packets_256_511(int argc, const char *argv[])
471 {
472         uint32_t port_id = atoi(argv[0]);
473         struct port_stats_sample *ps;
474
475         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
476                 return -1;
477         ps = stats_get_port_stats_sample(port_id, 1);
478         return ps->tx_pkt_size[PKT_SIZE_256];
479 }
480
481 static uint64_t sp_port_tx_packets_512_1023(int argc, const char *argv[])
482 {
483         uint32_t port_id = atoi(argv[0]);
484         struct port_stats_sample *ps;
485
486         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
487                 return -1;
488         ps = stats_get_port_stats_sample(port_id, 1);
489         return ps->tx_pkt_size[PKT_SIZE_512];
490 }
491
492 static uint64_t sp_port_tx_packets_1024_1522(int argc, const char *argv[])
493 {
494         uint32_t port_id = atoi(argv[0]);
495         struct port_stats_sample *ps;
496
497         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
498                 return -1;
499         ps = stats_get_port_stats_sample(port_id, 1);
500         return ps->tx_pkt_size[PKT_SIZE_1024];
501 }
502
503 static uint64_t sp_port_tx_packets_1523_max(int argc, const char *argv[])
504 {
505         uint32_t port_id = atoi(argv[0]);
506         struct port_stats_sample *ps;
507
508         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
509                 return -1;
510         ps = stats_get_port_stats_sample(port_id, 1);
511         return ps->tx_pkt_size[PKT_SIZE_1522];
512 }
513
514 static uint64_t sp_port_tsc(int argc, const char *argv[])
515 {
516         uint32_t port_id = atoi(argv[0]);
517         struct port_stats_sample *ps;
518
519         if (port_id > PROX_MAX_PORTS || !prox_port_cfg[port_id].active)
520                 return -1;
521         ps = stats_get_port_stats_sample(port_id, 1);
522         return ps->tsc;
523 }
524
525 static uint64_t sp_latency_max(int argc, const char *argv[])
526 {
527         struct stats_latency *lat_test = NULL;
528
529         if (atoi(argv[0]) >= stats_get_n_latency())
530                 return -1;
531         lat_test = stats_latency_get(atoi(argv[0]));
532
533         if (!lat_test->tot_packets)
534                 return -1;
535
536         struct time_unit tu = lat_test->max.time;
537         return time_unit_to_usec(&tu);
538 }
539
540 static uint64_t sp_latency_avg(int argc, const char *argv[])
541 {
542         struct stats_latency *lat_test = NULL;
543
544         if (atoi(argv[0]) >= stats_get_n_latency())
545                 return -1;
546         lat_test = stats_latency_get(atoi(argv[0]));
547
548         if (!lat_test->tot_packets)
549                 return -1;
550
551         struct time_unit tu = lat_test->avg.time;
552         return time_unit_to_usec(&tu);
553 }
554
555 static uint64_t sp_latency_lost(int argc, const char *argv[])
556 {
557         struct stats_latency *lat_test = NULL;
558
559         if (atoi(argv[0]) >= stats_get_n_latency())
560                 return -1;
561         lat_test = stats_latency_get(atoi(argv[0]));
562
563         if (!lat_test->tot_packets)
564                 return -1;
565
566         return lat_test->lost_packets;
567 }
568
569 static uint64_t sp_latency_tot_lost(int argc, const char *argv[])
570 {
571         struct stats_latency *lat_test = NULL;
572
573         if (atoi(argv[0]) >= stats_get_n_latency())
574                 return -1;
575         lat_test = stats_latency_tot_get(atoi(argv[0]));
576
577         if (!lat_test->tot_packets)
578                 return -1;
579
580         return lat_test->lost_packets;
581 }
582
583 static uint64_t sp_latency_total(int argc, const char *argv[])
584 {
585         struct stats_latency *lat_test = NULL;
586
587         if (atoi(argv[0]) >= stats_get_n_latency())
588                 return -1;
589         lat_test = stats_latency_get(atoi(argv[0]));
590
591         if (!lat_test->tot_all_packets)
592                 return -1;
593
594         return lat_test->tot_all_packets;
595 }
596
597 static uint64_t sp_latency_used(int argc, const char *argv[])
598 {
599         struct stats_latency *lat_test = NULL;
600
601         if (atoi(argv[0]) >= stats_get_n_latency())
602                 return -1;
603         lat_test = stats_latency_get(atoi(argv[0]));
604
605         if (!lat_test->tot_all_packets)
606                 return -1;
607
608         return lat_test->tot_packets;
609 }
610
611 static uint64_t sp_latency_tot_total(int argc, const char *argv[])
612 {
613         struct stats_latency *lat_test = NULL;
614
615         if (atoi(argv[0]) >= stats_get_n_latency())
616                 return -1;
617         lat_test = stats_latency_tot_get(atoi(argv[0]));
618
619         if (!lat_test->tot_all_packets)
620                 return -1;
621
622         return lat_test->tot_all_packets;
623 }
624
625 static uint64_t sp_latency_tot_used(int argc, const char *argv[])
626 {
627         struct stats_latency *lat_test = NULL;
628
629         if (atoi(argv[0]) >= stats_get_n_latency())
630                 return -1;
631         lat_test = stats_latency_tot_get(atoi(argv[0]));
632
633         if (!lat_test->tot_all_packets)
634                 return -1;
635
636         return lat_test->tot_packets;
637 }
638
639 static uint64_t sp_latency_tot_min(int argc, const char *argv[])
640 {
641         struct stats_latency *lat_test = NULL;
642
643         if (atoi(argv[0]) >= stats_get_n_latency())
644                 return -1;
645         lat_test = stats_latency_tot_get(atoi(argv[0]));
646
647         if (!lat_test->tot_packets)
648                 return -1;
649
650         struct time_unit tu = lat_test->min.time;
651         return time_unit_to_usec(&tu);
652 }
653
654 static uint64_t sp_latency_tot_max(int argc, const char *argv[])
655 {
656         struct stats_latency *lat_test = NULL;
657
658         if (atoi(argv[0]) >= stats_get_n_latency())
659                 return -1;
660         lat_test = stats_latency_tot_get(atoi(argv[0]));
661
662         if (!lat_test->tot_packets)
663                 return -1;
664
665         struct time_unit tu = lat_test->max.time;
666         return time_unit_to_usec(&tu);
667 }
668
669 static uint64_t sp_latency_tot_avg(int argc, const char *argv[])
670 {
671         struct stats_latency *lat_test = NULL;
672
673         if (atoi(argv[0]) >= stats_get_n_latency())
674                 return -1;
675         lat_test = stats_latency_tot_get(atoi(argv[0]));
676
677         if (!lat_test->tot_packets)
678                 return -1;
679
680         struct time_unit tu = lat_test->avg.time;
681         return time_unit_to_usec(&tu);
682 }
683
684 static uint64_t sp_latency_stddev(int argc, const char *argv[])
685 {
686         struct stats_latency *lat_test = NULL;
687
688         if (atoi(argv[0]) >= stats_get_n_latency())
689                 return -1;
690         lat_test = stats_latency_get(atoi(argv[0]));
691
692         if (!lat_test->tot_packets)
693                 return -1;
694
695         struct time_unit tu = lat_test->stddev.time;
696         return time_unit_to_usec(&tu);
697 }
698
699 static uint64_t sp_ring_used(int argc, const char *argv[])
700 {
701         struct ring_stats *rs = NULL;
702
703         if (atoi(argv[0]) >= stats_get_n_rings())
704                 return -1;
705         rs = stats_get_ring_stats(atoi(argv[0]));
706         return rs->size - rs->free;
707 }
708
709 static uint64_t sp_ring_free(int argc, const char *argv[])
710 {
711         struct ring_stats *rs = NULL;
712
713         if (atoi(argv[0]) >= stats_get_n_rings())
714                 return -1;
715         rs = stats_get_ring_stats(atoi(argv[0]));
716         return rs->free;
717 }
718
719 static uint64_t sp_ring_size(int argc, const char *argv[])
720 {
721         struct ring_stats *rs = NULL;
722
723         if (atoi(argv[0]) >= stats_get_n_rings())
724                 return -1;
725         rs = stats_get_ring_stats(atoi(argv[0]));
726         return rs->size;
727 }
728
729 static uint64_t sp_global_host_rx_packets(int argc, const char *argv[])
730 {
731         return stats_get_global_stats(1)->host_rx_packets;
732 }
733
734 static uint64_t sp_global_host_tx_packets(int argc, const char *argv[])
735 {
736         return stats_get_global_stats(1)->host_tx_packets;
737 }
738
739 static uint64_t sp_global_nics_rx_packets(int argc, const char *argv[])
740 {
741         return stats_get_global_stats(1)->nics_rx_packets;
742 }
743
744 static uint64_t sp_global_nics_tx_packets(int argc, const char *argv[])
745 {
746         return stats_get_global_stats(1)->nics_tx_packets;
747 }
748
749 static uint64_t sp_global_nics_ierrors(int argc, const char *argv[])
750 {
751         return stats_get_global_stats(1)->nics_ierrors;
752 }
753
754 static uint64_t sp_global_nics_imissed(int argc, const char *argv[])
755 {
756         return stats_get_global_stats(1)->nics_imissed;
757 }
758
759 static uint64_t sp_global_tsc(int argc, const char *argv[])
760 {
761         return stats_get_global_stats(1)->tsc;
762 }
763
764 static uint64_t sp_hz(int argc, const char *argv[])
765 {
766         return rte_get_tsc_hz();
767 }
768
769 struct stats_path_str stats_paths[] = {
770         {"hz", sp_hz},
771
772         {"global.host.rx.packets", sp_global_host_rx_packets},
773         {"global.host.tx.packets", sp_global_host_tx_packets},
774         {"global.nics.rx.packets", sp_global_nics_rx_packets},
775         {"global.nics.tx.packets", sp_global_nics_tx_packets},
776         {"global.nics.ierrrors", sp_global_nics_ierrors},
777         {"global.nics.imissed", sp_global_nics_imissed},
778         {"global.tsc", sp_global_tsc},
779
780         {"task.core(#).task(#).idle_cycles", sp_task_idle_cycles},
781         {"task.core(#).task(#).rx.packets", sp_task_rx_packets},
782         {"task.core(#).task(#).tx.packets", sp_task_tx_packets},
783         {"task.core(#).task(#).drop.tx_fail", sp_task_drop_tx_fail},
784         {"task.core(#).task(#).drop.discard", sp_task_drop_discard},
785         {"task.core(#).task(#).drop.handled", sp_task_drop_handled},
786         {"task.core(#).task(#).rx.bytes", sp_task_rx_bytes},
787         {"task.core(#).task(#).tx.bytes", sp_task_tx_bytes},
788         {"task.core(#).task(#).tsc", sp_task_tsc},
789         {"task.core(#).task(#).drop.tx_fail_prio(#)", sp_task_drop_tx_fail_prio},
790         {"task.core(#).task(#).rx_prio(#)", sp_task_rx_prio},
791         {"task.core(#).task(#).max_irq", sp_task_max_irq},
792         {"task.core(#).task(#).irq(#)", sp_task_irq},
793
794         {"port(#).no_mbufs", sp_port_no_mbufs},
795         {"port(#).ierrors", sp_port_ierrors},
796         {"port(#).imissed", sp_port_imissed},
797         {"port(#).oerrors", sp_port_oerrors},
798         {"port(#).rx.packets", sp_port_rx_packets},
799         {"port(#).tx.packets", sp_port_tx_packets},
800         {"port(#).rx.bytes", sp_port_rx_bytes},
801         {"port(#).tx.bytes", sp_port_tx_bytes},
802         {"port(#).tx.packets_64", sp_port_tx_packets_64},
803         {"port(#).tx.packets_65_127", sp_port_tx_packets_65_127},
804         {"port(#).tx.packets_128_255", sp_port_tx_packets_128_255},
805         {"port(#).tx.packets_256_511", sp_port_tx_packets_256_511},
806         {"port(#).tx.packets_512_1023", sp_port_tx_packets_512_1023},
807         {"port(#).tx.packets_1024_1522", sp_port_tx_packets_1024_1522},
808         {"port(#).tx.packets_1523_max", sp_port_tx_packets_1523_max},
809         {"port(#).tsc", sp_port_tsc},
810
811         {"mem(#).used", sp_mem_used},
812         {"mem(#).free", sp_mem_free},
813         {"mem(#).size", sp_mem_size},
814
815         {"latency(#).min", sp_latency_min},
816         {"latency(#).max", sp_latency_max},
817         {"latency(#).avg", sp_latency_avg},
818         {"latency(#).lost", sp_latency_lost},
819         {"latency(#).used", sp_latency_used},
820         {"latency(#).total", sp_latency_total},
821         {"latency(#).tot.min", sp_latency_tot_min},
822         {"latency(#).tot.max", sp_latency_tot_max},
823         {"latency(#).tot.avg", sp_latency_tot_avg},
824         {"latency(#).tot.lost", sp_latency_tot_lost},
825         {"latency(#).tot.used", sp_latency_tot_used},
826         {"latency(#).tot.total", sp_latency_tot_total},
827         {"latency(#).stddev", sp_latency_stddev},
828
829         {"ring(#).used", sp_ring_used},
830         {"ring(#).free", sp_ring_free},
831         {"ring(#).size", sp_ring_size},
832
833         {"l4gen(#).created.tcp", sp_l4gen_created_tcp},
834         {"l4gen(#).created.udp", sp_l4gen_created_udp},
835         {"l4gen(#).created.all", sp_l4gen_created_all},
836         {"l4gen(#).created.bundles", sp_l4gen_created_bundles},
837         {"l4gen(#).torndown.no_retx", sp_l4gen_torndown_no_retx},
838         {"l4gen(#).torndown.retx", sp_l4gen_torndown_retx},
839         {"l4gen(#).torndown.udp", sp_l4gen_torndown_udp},
840         {"l4gen(#).expired.tcp", sp_l4gen_expire_tcp},
841         {"l4gen(#).expired.udp", sp_l4gen_expire_udp},
842         {"l4gen(#).created", sp_l4gen_created},
843         {"l4gen(#).finished", sp_l4gen_finished},
844         {"l4gen(#).retx", sp_l4gen_retx},
845         {"l4gen(#).tsc", sp_l4gen_tsc},
846 };
847
848 static int stats_parser_extract_args(char *stats_path, size_t *argc, char **argv)
849 {
850         size_t len = strlen(stats_path);
851         size_t j = 0;
852         size_t k = 0;
853         int state = 0;
854
855         for (size_t i = 0; i < len; ++i) {
856                 switch (state) {
857                 case 0:
858                         if (stats_path[i] == '(') {
859                                 state = 1;
860                                 k = 0;
861                         }
862                         else if (stats_path[i] == ')')
863                                 return -1;
864                         stats_path[j] = stats_path[i];
865                         j++;
866                         break;
867                 case 1:
868                         if (stats_path[i] == ')') {
869                                 state = 0;
870                                 stats_path[j] = '#';
871                                 j++;
872                                 stats_path[j] = ')';
873                                 j++;
874                                 (*argc)++;
875                         }
876                         else {
877                                 argv[*argc][k++] = stats_path[i];
878                         }
879                         break;
880                 }
881         }
882         if (state == 1)
883                 return -1;
884         stats_path[j] = 0;
885         return 0;
886 }
887
888 uint64_t stats_parser_get(const char *stats_path)
889 {
890         size_t stats_path_len;
891
892         char stats_path_cpy[128];
893
894         strncpy(stats_path_cpy, stats_path, sizeof(stats_path_cpy));
895         stats_path_len = strlen(stats_path);
896
897         size_t max_argc = 16;
898         size_t argc = 0;
899         char argv_data[16][16] = {{0}};
900         char *argv[16];
901         const char *argv_c[16];
902
903         for (size_t i = 0; i < 16; ++i) {
904                 argv[i] = argv_data[i];
905                 argv_c[i] = argv_data[i];
906         }
907
908         if (stats_parser_extract_args(stats_path_cpy, &argc, argv))
909                 return -1;
910
911         for (size_t i = 0; i < sizeof(stats_paths)/sizeof(stats_paths[0]); ++i) {
912                 if (strcmp(stats_paths[i].str, stats_path_cpy) == 0) {
913                         if (stats_paths[i].func == NULL)
914                                 return -1;
915                         return stats_paths[i].func(argc, argv_c);
916                 }
917         }
918
919         return -1;
920 }