LCOV - code coverage report
Current view: top level - root/contrail/vrouter/utils - dpdkinfo.c (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 59 182 32.4 %
Date: 2026-06-18 01:51:13 Functions: 7 8 87.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * dpdkinfo.c - CLI dpdkinfo to get info. about bond, lacp, mem etc.
       3             :  *
       4             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       5             :  */
       6             : 
       7             : #include <stdio.h>
       8             : #include <stdlib.h>
       9             : #include <unistd.h>
      10             : #include <string.h>
      11             : #include <errno.h>
      12             : #include <inttypes.h>
      13             : #include <stdlib.h>
      14             : #include <stdbool.h>
      15             : #include <getopt.h>
      16             : 
      17             : #include <sys/types.h>
      18             : #include <sys/socket.h>
      19             : 
      20             : #include <net/if.h>
      21             : 
      22             : #include "ini_parser.h"
      23             : #include "vr_os.h"
      24             : #include "vr_types.h"
      25             : #include "vr_nexthop.h"
      26             : #include "ini_parser.h"
      27             : #include "nl_util.h"
      28             : #include "ini_parser.h"
      29             : #include "vr_packet.h"
      30             : #include "vr_interface.h"
      31             : 
      32             : static struct nl_client *cl;
      33             : static bool dump_pending = false;
      34             : static int dump_marker = -1;
      35             : /* For supporting multiple CLI clients, Message buffer table id is stored and
      36             :  * resend if dump_pending is true */
      37             : /* Optional parameter: buffsz -> Send buffer size for the Output buffer(outbuf)
      38             :  * */
      39             : static int buff_table_id, buffsz;
      40             : 
      41             : static int help_set, ver_set, bond_set, lacp_set, mempool_set, stats_set,
      42             :              xstats_set, lcore_set, app_set, ddp_set, sock_dir_set, link_set;
      43             : static unsigned int core = (unsigned)-1;
      44             : static unsigned int stats_index = 0;
      45             : /* For few  CLI, Inbuf has to send to vrouter for processing(i.e kind of filter
      46             : */
      47             : static uint8_t *vr_info_inbuf;
      48             : 
      49             : static vr_info_msg_en msginfo;
      50             : 
      51             : enum opt_index {
      52             :     HELP_OPT_INDEX,
      53             :     VER_OPT_INDEX,
      54             :     BOND_OPT_INDEX,
      55             :     LACP_OPT_INDEX,
      56             :     MEMPOOL_OPT_INDEX,
      57             :     STATS_OPT_INDEX,
      58             :     XSTATS_OPT_INDEX,
      59             :     BUFFSZ_OPT_INDEX,
      60             :     LCORE_OPT_INDEX,
      61             :     APP_OPT_INDEX,
      62             :     DDP_OPT_INDEX,
      63             :     SOCK_DIR_OPT_INDEX,
      64             :     LINK_OPT_INDEX,
      65             :     MAX_OPT_INDEX,
      66             : };
      67             : 
      68             : static struct option long_options[] = {
      69             :     [HELP_OPT_INDEX]    =   {"help",    no_argument,        &help_set,      1},
      70             :     [VER_OPT_INDEX]    =   {"version",    no_argument,        &ver_set,      1},
      71             :     [BOND_OPT_INDEX]    =   {"bond",    no_argument,        &bond_set,      1},
      72             :     [LACP_OPT_INDEX]    =   {"lacp",    required_argument,        &lacp_set,      1},
      73             :     [MEMPOOL_OPT_INDEX] =   {"mempool", required_argument,        &mempool_set,      1},
      74             :     [STATS_OPT_INDEX]    =   {"stats",    required_argument,        &stats_set,      1},
      75             :     [XSTATS_OPT_INDEX]    =   {"xstats",  optional_argument,        &xstats_set,      1},
      76             :     [LCORE_OPT_INDEX]    =   {"lcore",    no_argument,        &lcore_set,      1},
      77             :     [APP_OPT_INDEX]    =   {"app",    no_argument,        &app_set,      1},
      78             :     [DDP_OPT_INDEX]    =   {"ddp",    required_argument,        &ddp_set,      1},
      79             :     [BUFFSZ_OPT_INDEX]  =   {"buffsz",  required_argument,  &buffsz,        1},
      80             :     [SOCK_DIR_OPT_INDEX]  = {"sock-dir", required_argument, &sock_dir_set,  1},
      81             :     [LINK_OPT_INDEX]    =   {"link", required_argument, &link_set,  1},
      82             :     [MAX_OPT_INDEX]     =   {NULL,    0,                  0,              0},
      83             : };
      84             : 
      85             : static void
      86           0 : Usage()
      87             : {
      88           0 :     printf("Usage: dpdkinfo [--help]\n");
      89           0 :     printf("                 --version|-v\
      90             :                                                       Show DPDK Version\n");
      91           0 :     printf("                 --bond|-b\
      92             :                                                          Show Master/Slave bond information\n");
      93           0 :     printf("                 --lacp|-l     <all/conf>\
      94             :                                           Show LACP information from DPDK\n");
      95           0 :     printf("                 --mempool|-m  <all/<mempool-name>>\
      96             :                                 Show Mempool information\n");
      97           0 :     printf("                 --stats|-n    <eth>\
      98             :                                                Show Stats information\n");
      99           0 :     printf("                 --xstats|-x   < =all/ =0(Master)/ =1(Slave(0))/ =2(Slave(1))>\
     100             :      Show Extended Stats information\n");
     101           0 :     printf("                 --lcore|-c\
     102             :                                                         Show Lcore information\n");
     103           0 :     printf("                 --app|-a\
     104             :                                                           Show App information\n");
     105           0 :     printf("                 --ddp|-d      <list>\
     106             :                                                    Show DDP information for X710 NIC\n");
     107           0 :     printf("       Optional: --buffsz      <value>\
     108             :                                              Send output buffer size (less than 1000Mb)\n");
     109           0 :     exit(-EINVAL);
     110             : }
     111             : 
     112             : static void
     113           1 : validate_options(void)
     114             : {
     115           1 :     if(!(ver_set || bond_set || lacp_set || mempool_set ||
     116           0 :         stats_set || xstats_set || lcore_set || app_set|| ddp_set || link_set))
     117           0 :         Usage();
     118             : 
     119           1 :     return;
     120             : }
     121             : 
     122             : /*
     123             :  * Response messages are sent through character buffer via Sandesh and it has
     124             :  * a limitation of sending upto 4K(PAGE_SIZE) for each iteration.
     125             :  * */
     126             : static void
     127           1 : dpdkinfo_resp_cb_process(void *s_req)
     128             : {
     129           1 :     int ret = 0;
     130           1 :     vr_info_req *resp = (vr_info_req *)s_req;
     131           1 :     if(resp != NULL && resp->vdu_proc_info) {
     132             :         /* Print the Message buffer(character buffer)
     133             :          * sent by vRouter(Server) */
     134           1 :         printf("%s", resp->vdu_proc_info);
     135             :     }
     136             : 
     137             :     /* For Sandesh DUMP, we should update the marker id and buff_table_id for
     138             :      * the next interation. */
     139           1 :     if (resp->h_op == SANDESH_OP_DUMP) {
     140           1 :         dump_marker = resp->vdu_index;
     141           1 :         buff_table_id = resp->vdu_buff_table_id;
     142             :     }
     143           1 : }
     144             : 
     145             : static void
     146           1 : response_process(void *s)
     147             : {
     148           1 :     vr_response_common_process((vr_response *)s, &dump_pending);
     149           1 : }
     150             : 
     151             : static void
     152           1 : dpdkinfo_fill_nl_callbacks()
     153             : {
     154           1 :     nl_cb.vr_info_req_process = dpdkinfo_resp_cb_process;
     155           1 :     nl_cb.vr_response_process = response_process;
     156           1 : }
     157             : 
     158             : static void
     159           2 : parse_long_opts(int opt_index, char *opt_arg)
     160             : {
     161           2 :     errno = 0;
     162             : 
     163           2 :     switch (opt_index) {
     164           0 :     case VER_OPT_INDEX:
     165           0 :         msginfo = INFO_VER_DPDK;
     166           0 :         break;
     167             : 
     168           0 :     case BOND_OPT_INDEX:
     169           0 :         msginfo = INFO_BOND;
     170           0 :         break;
     171             : 
     172           0 :     case LACP_OPT_INDEX:
     173           0 :         msginfo = INFO_LACP;
     174           0 :         if (!strcmp(opt_arg, "all") || !strcmp(opt_arg, "conf")){
     175           0 :             vr_info_inbuf = opt_arg;
     176             :         } else {
     177           0 :             Usage();
     178             :         }
     179           0 :         break;
     180             : 
     181           1 :     case MEMPOOL_OPT_INDEX:
     182           1 :         msginfo = INFO_MEMPOOL;
     183           1 :         vr_info_inbuf = opt_arg;
     184           1 :         break;
     185             : 
     186           0 :     case STATS_OPT_INDEX:
     187           0 :         msginfo = INFO_STATS;
     188           0 :         if (strcmp(opt_arg,"eth") == 0){
     189           0 :             vr_info_inbuf = opt_arg;
     190             :         } else {
     191           0 :             Usage();
     192             :         }
     193           0 :         break;
     194             : 
     195           0 :     case XSTATS_OPT_INDEX:
     196           0 :         msginfo = INFO_XSTATS;
     197           0 :         if (!opt_arg){
     198           0 :             opt_arg = "";
     199             :         }
     200           0 :         if (!strcmp(opt_arg, "all") || !strcmp(opt_arg, "") ||
     201           0 :             !strcmp(opt_arg, "0") || ((atoi(opt_arg) > 0) &&
     202           0 :                            (atoi(opt_arg) <= VR_INTERFACE_BOND_MAX_SLAVES))){
     203           0 :             vr_info_inbuf = opt_arg;
     204             :         } else {
     205           0 :             Usage();
     206             :         }
     207           0 :         break;
     208             : 
     209           0 :     case LCORE_OPT_INDEX:
     210           0 :         msginfo = INFO_LCORE;
     211           0 :         break;
     212             : 
     213           0 :     case APP_OPT_INDEX:
     214           0 :         msginfo = INFO_APP;
     215           0 :         break;
     216             : 
     217           0 :     case DDP_OPT_INDEX:
     218           0 :         msginfo = INFO_DDP;
     219           0 :         if (!strcmp(opt_arg, "list")){
     220           0 :             vr_info_inbuf = opt_arg;
     221             :         } else {
     222           0 :             Usage();
     223             :         }
     224           0 :         break;
     225             : 
     226           1 :     case SOCK_DIR_OPT_INDEX:
     227           1 :         vr_socket_dir = opt_arg;
     228           1 :         break;
     229             : 
     230           0 :     case BUFFSZ_OPT_INDEX:
     231             :         /* Setting buffsz limit to 1000Mb */
     232           0 :         if ((unsigned)strtol(opt_arg, NULL, 0) >= 0x3E800000){
     233           0 :             Usage();
     234             :         }
     235           0 :         buffsz = (unsigned)strtol(opt_arg, NULL, 0);
     236           0 :         break;
     237             : 
     238           0 :     case LINK_OPT_INDEX:
     239           0 :         msginfo = INFO_LINK;
     240           0 :         vr_info_inbuf = opt_arg;
     241           0 :         break;
     242             : 
     243           0 :     case HELP_OPT_INDEX:
     244             :     default:
     245           0 :         Usage();
     246             :     }
     247             : 
     248           2 :     return;
     249             : }
     250             : 
     251             : /* vr_get_dpdkinfo API send request to vRouter(server) and uses
     252             :  * h_op = DUMP for message request.
     253             :  *  */
     254             : static int
     255           1 : vr_get_dpdkinfo(struct nl_client *cl)
     256             : {
     257             :     int ret;
     258           1 :     bool dump = true;
     259             : 
     260           1 : op_retry:
     261           1 :     ret = vr_send_info_dump(cl, 0, dump_marker, buff_table_id, msginfo, buffsz,
     262             :             vr_info_inbuf);
     263           1 :     if (ret < 0)
     264           0 :         return ret;
     265             : 
     266           1 :     ret = vr_recvmsg(cl, dump);
     267           1 :     if (ret <= 0)
     268           0 :         return ret;
     269             : 
     270             :     /* Will loop through till it reaches end of buffer */
     271           1 :     if (dump_pending)
     272           0 :         goto op_retry;
     273           1 :     return 0;
     274             : }
     275             : 
     276             : int
     277           1 : main(int argc, char *argv[])
     278             : {
     279             :     char opt;
     280           1 :     int ret, option_index, log_core = 0, i = 0;
     281           1 :     int platform = 0;
     282             : 
     283             :     /* Register callback function for Netlink message */
     284           1 :     dpdkinfo_fill_nl_callbacks();
     285             : 
     286           1 :     parse_ini_file();
     287             : 
     288           3 :     while (((opt = getopt_long(argc, argv, "-:hvbl:m:sn:p:d:cax::",
     289           3 :                         long_options, &option_index)) >= 0)) {
     290           2 :         switch (opt) {
     291           0 :         case 'v':
     292           0 :             ver_set = 1;
     293           0 :             msginfo = INFO_VER_DPDK;
     294           0 :             break;
     295             : 
     296           0 :         case 'b':
     297           0 :             bond_set = 1;
     298           0 :             msginfo = INFO_BOND;
     299           0 :             break;
     300             : 
     301           0 :         case 'l':
     302           0 :             lacp_set = 1;
     303           0 :             msginfo = INFO_LACP;
     304           0 :             parse_long_opts(LACP_OPT_INDEX, optarg);
     305           0 :             break;
     306             : 
     307           0 :         case 'm':
     308           0 :             mempool_set = 1;
     309           0 :             msginfo = INFO_MEMPOOL;
     310           0 :             parse_long_opts(MEMPOOL_OPT_INDEX, optarg);
     311           0 :             break;
     312             : 
     313           0 :         case 'n':
     314           0 :             stats_set = 1;
     315           0 :             msginfo = INFO_STATS;
     316           0 :             parse_long_opts(STATS_OPT_INDEX, optarg);
     317           0 :             break;
     318             : 
     319           0 :         case 's':
     320           0 :             sock_dir_set = 1;
     321           0 :             parse_long_opts(SOCK_DIR_OPT_INDEX, optarg);
     322           0 :             break;
     323             : 
     324           0 :         case 'x':
     325           0 :             xstats_set = 1;
     326           0 :             msginfo = INFO_XSTATS;
     327           0 :             parse_long_opts(XSTATS_OPT_INDEX, optarg);
     328           0 :             break;
     329             : 
     330           0 :         case 'c':
     331           0 :             lcore_set = 1;
     332           0 :             msginfo = INFO_LCORE;
     333           0 :             break;
     334             : 
     335           0 :         case 'a':
     336           0 :             app_set = 1;
     337           0 :             msginfo = INFO_APP;
     338           0 :             break;
     339             : 
     340           0 :         case 'p':
     341           0 :             link_set = 1;
     342           0 :             msginfo = INFO_LINK;
     343           0 :             parse_long_opts(LINK_OPT_INDEX, optarg);
     344           0 :             break;
     345             : 
     346           0 :         case 'd':
     347           0 :             ddp_set = 1;
     348           0 :             msginfo = INFO_DDP;
     349           0 :             parse_long_opts(DDP_OPT_INDEX, optarg);
     350           0 :             break;
     351             : 
     352           2 :         case 0:
     353           2 :             parse_long_opts(option_index, optarg);
     354           2 :             break;
     355             : 
     356           0 :         case 'h':
     357             :         default:
     358           0 :             Usage();
     359             :         }
     360             :     }
     361           1 :     validate_options();
     362             : 
     363             :     /* Support for running from VTEST(vRouter UT Framework)*/
     364           1 :     if (sock_dir_set) {
     365           1 :         set_platform_vtest();
     366             :     }
     367           1 :     platform = get_platform();
     368           1 :     if ((platform != DPDK_PLATFORM) && (platform != VTEST_PLATFORM)) {
     369           0 :         Usage();
     370             :     }
     371             : 
     372           1 :     cl = vr_get_nl_client(VR_NETLINK_PROTO_DEFAULT);
     373           1 :     if (!cl)
     374           0 :         return -1;
     375             : 
     376           1 :     vr_get_dpdkinfo(cl);
     377             : 
     378           1 :     return 0;
     379             : }

Generated by: LCOV version 1.14