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