LCOV - code coverage report
Current view: top level - root/contrail/vrouter/dpdk - vr_dpdk_info.c (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 31 720 4.3 %
Date: 2026-11-09 02:10:49 Functions: 2 20 10.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * vr_dpdk_info.c - DPDK specific callback functions for vr_info .
       3             :  *
       4             :  * Copyright (c) 2020 Juniper Networks, Inc. All rights reserved.
       5             :  * Copyright Contributors to the OpenSDN project
       6             :  */
       7             : #include <vr_os.h>
       8             : #include <vr_types.h>
       9             : #include <string.h>
      10             : #include <sys/types.h>
      11             : #include <sys/stat.h>
      12             : #include <fcntl.h>
      13             : 
      14             : #include <vr_packet.h>
      15             : #include <rte_eth_bond.h>
      16             : #include <rte_ethdev.h>
      17             : #include <rte_port_ethdev.h>
      18             : #include <rte_eth_bond_8023ad.h>
      19             : #include <rte_pmd_i40e.h>
      20             : #include <rte_malloc.h>
      21             : #include <rte_mempool.h>
      22             : #include "vr_message.h"
      23             : #include "vr_btable.h"
      24             : #include "vr_dpdk.h"
      25             : #include "vrouter.h"
      26             : 
      27             : #define SEPERATOR 70
      28             : #define LINE 200
      29             : #define MAXBITS 8
      30             : #define I40E_MAX_PROFILE_NUM 16
      31             : 
      32             : enum segments {
      33             :     RX_PACKETS,
      34             :     RX_BYTES,
      35             :     TX_PACKETS,
      36             :     TX_BYTES,
      37             :     ERRORS,
      38             :     OTHERS
      39             : };
      40             : 
      41             : /* NOTE: Callback API's need to be registered in vrouter/include/vr_info.h
      42             :  * under VR_INFO_REG(X) macro.
      43             :  * All callback API's should start with "dpdk_<fn.name>"
      44             :  * Register Format: X(MSG, <fn.name>) \
      45             :  *              eg: X(INFO_BOND, info_get_bond)
      46             :  */
      47             : 
      48             : int
      49           0 : dpdk_info_get_dpdk_version(VR_INFO_ARGS)
      50             : {
      51             :     extern const char *ContrailBuildInfo;
      52             : 
      53           0 :     VR_INFO_BUF_INIT();
      54             : 
      55           0 :     VI_PRINTF("DPDK Version: %s\n",
      56             :         rte_version());
      57           0 :     VI_PRINTF("vRouter version: %s\n\n", ContrailBuildInfo);
      58           0 :     return 0;
      59             : }
      60             : 
      61             : int
      62           0 : get_port_states(VR_INFO_ARGS, uint8_t state)
      63             : {
      64           0 :    VR_INFO_DEC();
      65           0 :    int i = 0, cur = 0;
      66           0 :    char *states[] = {"ACT", "TIMEOUT", "AGG", "SYNC", "COL", "DIST",
      67             :                      "DEF", "EXP"};
      68           0 :    uint8_t orig_state = state;
      69           0 :    char port_states[LINE] = "";
      70             : 
      71             :    /* Iterating through each bit */
      72           0 :    while (i <= MAXBITS){
      73           0 :        if ((1 & state) && (cur < LINE)){
      74           0 :            cur += snprintf(port_states + cur, LINE - cur, "%s ", states[i]);
      75             :        }
      76           0 :        state  = state >> 1;
      77           0 :        i++;
      78             :    }
      79           0 :    VI_PRINTF("\tport state: %d (%s) \n\n", orig_state, port_states);
      80           0 :    return 0;
      81             : }
      82             : 
      83             : /* dpdk_info_get_bond provide the bond master & slave information */
      84             : static int
      85           0 : dpdk_bond_mode_8023ad(VR_INFO_ARGS, uint16_t port_id)
      86             : {
      87           0 :     VR_INFO_DEC();
      88             :     int ret;
      89           0 :     char *lacp_rate[] = {"slow", "fast"};
      90             : 
      91           0 :     VI_PRINTF("802.3ad info :\n");
      92             : 
      93           0 :     VI_PRINTF("LACP Rate: %s\n",
      94             :             lacp_rate[rte_eth_bond_lacp_rate_get(port_id)]);
      95             : 
      96           0 :     ret = rte_eth_bond_8023ad_agg_selection_get(port_id);
      97           0 :     switch(ret) {
      98           0 :         case AGG_COUNT:
      99           0 :             VI_PRINTF("Aggregator selection policy (ad_select): Count\n");
     100           0 :             break;
     101           0 :         case AGG_BANDWIDTH:
     102           0 :             VI_PRINTF("Aggregator selection policy (ad_select): Bandwidth\n");
     103           0 :             break;
     104           0 :         case AGG_STABLE:
     105           0 :             VI_PRINTF("Aggregator selection policy (ad_select): Stable\n");
     106           0 :             break;
     107           0 :         default:
     108           0 :             VI_PRINTF("Aggregator selection policy (ad_select): Null\n");
     109             :     }
     110             : 
     111           0 :     return 0;
     112             : }
     113             : 
     114             : static int
     115           0 : dpdk_bond_info_mii_status(VR_INFO_ARGS, uint16_t port_id,
     116             :                                    struct rte_eth_link *link)
     117             : {
     118           0 :     VR_INFO_DEC();
     119           0 :     char *status[] = {"DOWN", "UP"};
     120             : 
     121           0 :     VI_PRINTF("MII status: %s\n", status[link->link_status]);
     122           0 :     VI_PRINTF("MII Link Speed: %d Mbps\n", link->link_speed);
     123           0 :     if(rte_eth_bond_mode_get(port_id) == BONDING_MODE_8023AD) {
     124           0 :         VI_PRINTF("MII Polling Interval (ms): %d\n",
     125             :                 rte_eth_bond_link_monitoring_get(port_id));
     126             :     }
     127           0 :     return 0;
     128             : }
     129             : 
     130             : static int
     131           0 : dpdk_bond_info_show_slave(VR_INFO_ARGS, uint16_t port_id,
     132             :                                struct vr_dpdk_ethdev *ethdev)
     133             : {
     134           0 :     VR_INFO_DEC();
     135             :     int i, ret;
     136             :     uint16_t slave_id;
     137           0 :     char *duplex[] = {"half", "full"};
     138             :     struct rte_ether_addr mac_addr;
     139             :     struct rte_eth_link link;
     140             :     char name[VR_INTERFACE_NAME_LEN];
     141             :     struct rte_eth_bond_8023ad_slave_info info;
     142             : 
     143             :     /* Display bond slave inforamtion */
     144           0 :     for (i = 0; i < ethdev->ethdev_nb_slaves; i++) {
     145           0 :         slave_id = ethdev->ethdev_slaves[i];
     146             : 
     147           0 :         ret = rte_eth_dev_get_name_by_port(slave_id, name);
     148           0 :         if (ret != 0) {
     149           0 :             RTE_LOG(ERR, VROUTER, "%s: Error getting slave interface name "
     150             :                                     "slave_id:%d \n", __func__, slave_id);
     151           0 :             return VR_INFO_FAILED;
     152             :         }
     153             : 
     154             : 
     155           0 :         VI_PRINTF("Slave Interface(%d): %s \n", i, name);
     156           0 :         VI_PRINTF("Slave Interface Driver: %s\n",
     157             :             rte_eth_devices[slave_id].device->driver->name);
     158             : 
     159           0 :         rte_eth_link_get_nowait(slave_id, &link);
     160           0 :         ret = dpdk_bond_info_mii_status(msg_req, slave_id, &link);
     161           0 :         if (ret < 0) {
     162           0 :             return VR_INFO_FAILED;
     163             :         }
     164             : 
     165           0 :         ret = rte_eth_bond_8023ad_slave_info(port_id, slave_id, &info);
     166           0 :         if (ret == 0) {
     167           0 :             VI_PRINTF("Permanent HW addr:"MAC_FORMAT "\n",
     168             :                           MAC_VALUE(info.actor.system.addr_bytes));
     169           0 :             VI_PRINTF("Aggregator ID: %d\n", info.agg_port_id);
     170             : 
     171           0 :             VI_PRINTF("Duplex: %s\n", duplex[link.link_duplex]);
     172             : 
     173           0 :             rte_eth_macaddr_get(slave_id, &mac_addr);
     174           0 :             VI_PRINTF("Bond MAC addr:"MAC_FORMAT "\n",
     175             :                         MAC_VALUE(mac_addr.addr_bytes));
     176             : 
     177           0 :             VI_PRINTF("Details actor lacp pdu: \n");
     178           0 :             VI_PRINTF("\tsystem priority: %"PRIu16"\n",
     179             :                         htons(info.actor.system_priority));
     180           0 :             VI_PRINTF("\tsystem mac address:"MAC_FORMAT "\n",
     181             :                         MAC_VALUE(info.actor.system.addr_bytes));
     182           0 :             VI_PRINTF("\tport key: %"PRIu16"\n", htons(info.actor.key));
     183           0 :             VI_PRINTF("\tport priority: %"PRIu16 "\n",
     184             :                         htons(info.actor.port_priority));
     185           0 :             VI_PRINTF("\tport number: %"PRIu16"\n",
     186             :                         htons(info.actor.port_number));
     187           0 :             get_port_states(msg_req, info.actor_state);
     188             : 
     189           0 :             VI_PRINTF("Details partner lacp pdu: \n");
     190           0 :             VI_PRINTF("\tsystem priority: %"PRIu16"\n",
     191             :                         htons(info.partner.system_priority));
     192           0 :             VI_PRINTF("\tsystem mac address:"MAC_FORMAT "\n",
     193             :                         MAC_VALUE(info.partner.system.addr_bytes));
     194           0 :             VI_PRINTF("\tport key: %"PRIu16"\n", htons(info.partner.key));
     195           0 :             VI_PRINTF("\tport priority: %"PRIu16"\n",
     196             :                         htons(info.partner.port_priority));
     197           0 :             VI_PRINTF("\tport number: %"PRIu16"\n",
     198             :                         htons(info.partner.port_number));
     199           0 :             get_port_states(msg_req, info.partner_state);
     200             :         } else {
     201           0 :             VI_PRINTF("\n");
     202             :         }
     203             :     }
     204           0 :     return 0;
     205             : }
     206             : 
     207             : static int
     208           0 : dpdk_bond_info_show_master(VR_INFO_ARGS, uint16_t port_id,
     209             :     struct vr_dpdk_ethdev *ethdev)
     210             : {
     211           0 :     VR_INFO_DEC();
     212             :     int ret, bond_mode;
     213             :     uint16_t slave_id;
     214             :     struct rte_eth_link link;
     215             :     struct rte_eth_bond_8023ad_slave_info info;
     216             : 
     217             :     /* Get bond mode */
     218           0 :     bond_mode = rte_eth_bond_mode_get(port_id);
     219           0 :     switch (bond_mode) {
     220           0 :     case BONDING_MODE_ROUND_ROBIN:
     221           0 :         VI_PRINTF("Bonding Mode: Round Robin\n");
     222           0 :         break;
     223           0 :     case BONDING_MODE_ACTIVE_BACKUP:
     224           0 :         VI_PRINTF("Bonding Mode: Active Backup\n");
     225           0 :         break;
     226           0 :     case BONDING_MODE_BALANCE:
     227           0 :         VI_PRINTF("Bonding Mode: Balance\n");
     228           0 :         break;
     229           0 :     case BONDING_MODE_BROADCAST:
     230           0 :         VI_PRINTF("Bonding Mode: Broadcast\n");
     231           0 :         break;
     232           0 :     case BONDING_MODE_8023AD:
     233           0 :         VI_PRINTF("Bonding Mode: 802.3AD Dynamic Link Aggregation\n");
     234           0 :         break;
     235           0 :     case BONDING_MODE_TLB:
     236           0 :         VI_PRINTF("Bonding Mode: Adaptive TLB(Trnasmit Load Balancing)\n");
     237           0 :         break;
     238           0 :     case BONDING_MODE_ALB:
     239           0 :         VI_PRINTF("Bonding Mode: Adaptive Load Balancing(Tx/Rx)\n");
     240           0 :         break;
     241           0 :     default:
     242           0 :         VI_PRINTF("Bonding Mode: None\n");
     243             :     }
     244             : 
     245             :     /* Transmit Hash Policy */
     246           0 :     ret = rte_eth_bond_xmit_policy_get(port_id);
     247           0 :     switch (ret) {
     248           0 :     case BALANCE_XMIT_POLICY_LAYER2:
     249           0 :         VI_PRINTF("Transmit Hash Policy: Layer 2 (Ethernet MAC)\n");
     250           0 :         break;
     251           0 :     case BALANCE_XMIT_POLICY_LAYER23:
     252           0 :         VI_PRINTF("Transmit Hash Policy: Layer 2+3 (Ethernet MAC + "
     253             :             "IP Addresses) transmit load balancing\n");
     254           0 :         break;
     255           0 :     case BALANCE_XMIT_POLICY_LAYER34:
     256           0 :         VI_PRINTF("Transmit Hash Policy: Layer 3+4 (IP Addresses + "
     257             :             "UDP Ports) transmit load balancing\n");
     258           0 :         break;
     259           0 :     default:
     260           0 :         VI_PRINTF("Transmit Hash Policy: None\n");
     261             :     }
     262             : 
     263           0 :     rte_eth_link_get_nowait(port_id, &link);
     264           0 :     ret = dpdk_bond_info_mii_status(msg_req, port_id, &link);
     265           0 :     if (ret < 0) {
     266           0 :         return VR_INFO_FAILED;
     267             :     }
     268             : 
     269           0 :     VI_PRINTF("Up Delay (ms): %d\n",
     270             :         rte_eth_bond_link_up_prop_delay_get(port_id));
     271           0 :     VI_PRINTF("Down Delay (ms): %d\n",
     272             :         rte_eth_bond_link_down_prop_delay_get(port_id));
     273           0 :     if(rte_eth_devices[port_id].device &&
     274           0 :             rte_eth_devices[port_id].device->driver) {
     275           0 :         VI_PRINTF("Driver: %s\n\n",
     276             :             rte_eth_devices[port_id].device->driver->name);
     277             :     }
     278             : 
     279           0 :     if (bond_mode == BONDING_MODE_8023AD) {
     280           0 :         ret = dpdk_bond_mode_8023ad(msg_req, port_id);
     281           0 :         if (ret < 0) {
     282           0 :             return VR_INFO_FAILED;
     283             :         }
     284             :     }
     285             : 
     286           0 :     slave_id = ethdev->ethdev_slaves[0];
     287             : 
     288           0 :     ret = rte_eth_bond_8023ad_slave_info(port_id, slave_id, &info);
     289           0 :     if (ret != 0) {
     290           0 :         RTE_LOG(ERR, VROUTER, "%s: Error getting slave info bond:%d slave:%d\n",
     291             :                                 __func__, port_id, slave_id);
     292           0 :         return VR_INFO_FAILED;
     293             :     }
     294             : 
     295           0 :     VI_PRINTF("System priority: %"PRIu16"\n", htons(info.actor.system_priority));
     296           0 :     VI_PRINTF("System MAC address:"MAC_FORMAT "\n",
     297             :         MAC_VALUE(info.actor.system.addr_bytes));
     298           0 :     VI_PRINTF("Active Aggregator Info: \n");
     299           0 :     VI_PRINTF("\tAggregator ID: %"PRIu16"\n", htons(info.agg_port_id));
     300           0 :     VI_PRINTF("\tNumber of ports: %d \n", ethdev->ethdev_nb_slaves);
     301           0 :     VI_PRINTF("\tActor Key: %"PRIu16"\n", htons(info.actor.key));
     302           0 :     VI_PRINTF("\tPartner Key: %"PRIu16"\n", htons(info.partner.key));
     303           0 :     VI_PRINTF("\tPartner Mac Address: "MAC_FORMAT "\n\n",
     304             :         MAC_VALUE(info.partner.system.addr_bytes));
     305           0 :     return 0;
     306             : }
     307             : 
     308             : /* dpdk_info_get_bond provide the bond master & slave information */
     309             : int
     310           0 : dpdk_info_get_bond(VR_INFO_ARGS)
     311             : {
     312             :     uint16_t port_id;
     313             :     struct vr_dpdk_bond_port_list port_list;
     314             :     struct vr_dpdk_ethdev *ethdev;
     315           0 :     char name[VR_INTERFACE_NAME_LEN] = "";
     316             :     int ret, i;
     317             : 
     318             :     /* If output buffer size(--buffsz) is sent from CLI, then allocate with
     319             :        that size else allocate with default size */
     320           0 :     VR_INFO_BUF_INIT();
     321             :     /* Get the port_id list for master, Incase of non-bond devices, it return here */
     322           0 :     if (!dpdk_find_bond_port_id_list(&port_list)) {
     323           0 :         RTE_LOG(ERR, VROUTER, "%s: Port Id list is invalid\n", __func__);
     324           0 :         return -1;
     325             :     }
     326             : 
     327           0 :     VI_PRINTF("No. of bond id available: %d\n", port_list.intf_count);
     328           0 :     for (i = 0; i < port_list.intf_count ; i++) {
     329           0 :         port_id = port_list.intf_list[i];
     330             :         /* Get the ethdev for master port. */
     331           0 :         ethdev = &vr_dpdk.ethdevs[port_id];
     332           0 :         if (ethdev == NULL ||
     333           0 :             ethdev->ethdev_ptr == NULL) {
     334           0 :             RTE_LOG(ERR, VROUTER, "%s: Ethdev not available port: %d\n",
     335             :                                    __func__, port_id);
     336           0 :             continue;
     337             :         }
     338             : 
     339           0 :         rte_eth_dev_get_name_by_port(port_id, name);
     340           0 :         VI_PRINTF("=================================================\n");
     341           0 :         VI_PRINTF("|| Bond : %s No. of bond slaves: %d ||\n",
     342             :                     name, ethdev->ethdev_nb_slaves);
     343           0 :         VI_PRINTF("=================================================\n");
     344             : 
     345           0 :         ret = dpdk_bond_info_show_master(msg_req, port_id, ethdev);
     346           0 :         if (ret < 0) {
     347           0 :             RTE_LOG(ERR, VROUTER, "%s failed to show master info port_id:%d(ret:%d)\n",
     348             :                     __func__, port_id, ret);
     349             :         }
     350             : 
     351           0 :         ret = dpdk_bond_info_show_slave(msg_req, port_id, ethdev);
     352           0 :         if (ret < 0) {
     353           0 :             RTE_LOG(ERR, VROUTER, "%s failed to show slave info port_id:%d(ret:%d)\n",
     354             :                     __func__, port_id, ret);
     355             :         }
     356             :     }
     357           0 :     return 0;
     358             : }
     359             : 
     360             : static int
     361           0 : display_lacp_conf(VR_INFO_ARGS, uint16_t port_id)
     362             : {
     363             : 
     364           0 :     VR_INFO_DEC();
     365           0 :     char *lacp_rate[] = {"slow","fast"};
     366             :     struct rte_eth_bond_8023ad_conf conf;
     367             : 
     368             :     /* Check LACP protocol is configured for the bond interface. */
     369           0 :     VI_PRINTF("LACP Rate: %s\n\n",
     370             :         lacp_rate[rte_eth_bond_lacp_rate_get(port_id)]);
     371             : 
     372           0 :     rte_eth_bond_8023ad_conf_get(port_id, &conf);
     373             : 
     374           0 :     VI_PRINTF("Fast periodic (ms): %d\n", conf.fast_periodic_ms);
     375           0 :     VI_PRINTF("Slow periodic (ms): %d\n", conf.slow_periodic_ms);
     376           0 :     VI_PRINTF("Short timeout (ms): %d\n", conf.short_timeout_ms);
     377           0 :     VI_PRINTF("Long timeout (ms): %d\n", conf.long_timeout_ms);
     378           0 :     VI_PRINTF("Aggregate wait timeout (ms): %d\n",
     379             :         conf.aggregate_wait_timeout_ms);
     380           0 :     VI_PRINTF("Tx period (ms): %d\n", conf.tx_period_ms);
     381           0 :     VI_PRINTF("Update timeout (ms): %d\n", conf.update_timeout_ms);
     382           0 :     VI_PRINTF("Rx marker period (ms): %d\n\n", conf.rx_marker_period_ms);
     383           0 :     return 0;
     384             : 
     385             : }
     386             : 
     387             : int
     388           0 : dpdk_info_get_lacp(VR_INFO_ARGS)
     389             : {
     390             : 
     391           0 :     uint16_t port_id, slave_id = 0;
     392             :     struct vr_dpdk_ethdev *ethdev;
     393             :     struct vr_dpdk_bond_port_list port_list;
     394           0 :     int i, j, ret = 0;
     395           0 :     char name[VR_INTERFACE_NAME_LEN] = "";
     396             :     struct rte_eth_bond_8023ad_slave_info info;
     397             :     uint64_t lacp_rx_cnt, lacp_tx_cnt;
     398             : 
     399             : 
     400           0 :     VR_INFO_BUF_INIT();
     401             : 
     402             :     /* expecting buf string to be either all or conf */
     403           0 :     if ((strcmp(msg_req->inbuf, "all") &&
     404           0 :         (strcmp(msg_req->inbuf, "conf")))) {
     405           0 :         RTE_LOG(ERR, VROUTER, "Invalid argument.\n");
     406           0 :         return -1;
     407             :     }
     408             : 
     409             :     /* Get the port_id list for master, Incase of non-bond devices,
     410             :        it return here. */
     411           0 :     if (!dpdk_find_bond_port_id_list(&port_list)) {
     412           0 :         RTE_LOG(ERR, VROUTER, "%s: Port Id is invalid\n", __func__);
     413           0 :         return -1;
     414             :     }
     415             : 
     416           0 :     VI_PRINTF("No. of bond ids: %d\n", port_list.intf_count);
     417           0 :     for (j = 0; j < port_list.intf_count; j++) {
     418           0 :         port_id = port_list.intf_list[j];
     419             : 
     420           0 :         rte_eth_dev_get_name_by_port(port_id, name);
     421           0 :         VI_PRINTF("=======================================\n");
     422           0 :         VI_PRINTF("|| Bond Interface(%d): %s ||\n", port_id, name);
     423           0 :         VI_PRINTF("=======================================\n");
     424             : 
     425           0 :         if (strcmp(msg_req->inbuf, "all") == 0) {
     426           0 :             ret = display_lacp_conf(msg_req, port_id);
     427             : 
     428           0 :             ethdev = &vr_dpdk.ethdevs[port_id];
     429           0 :             if (ethdev == NULL ||
     430           0 :                 ethdev->ethdev_ptr == NULL) {
     431           0 :                 RTE_LOG(ERR, VROUTER, "%s: Ethdev not available port id: %d\n",
     432             :                                        __func__, port_id);
     433           0 :                 continue;
     434             :             }
     435             : 
     436             :             /* Displaying bond slave inforamtion */
     437           0 :             for (i = 0; i < ethdev->ethdev_nb_slaves; i++) {
     438           0 :                 slave_id = ethdev->ethdev_slaves[i];
     439             : 
     440           0 :                 ret = rte_eth_dev_get_name_by_port(slave_id, name);
     441           0 :                 if (ret != 0) {
     442           0 :                     RTE_LOG(ERR, VROUTER, "%s: Error getting dev name "
     443             :                             "port: %d slave: %d \n", __func__, port_id, slave_id);
     444           0 :                     continue;
     445             :                 }
     446             : 
     447           0 :                 VI_PRINTF("Slave Interface(%d): %s \n", i, name);
     448             : 
     449           0 :                 ret = rte_eth_bond_8023ad_slave_info(port_id, slave_id, &info);
     450           0 :                 if (ret == 0) {
     451           0 :                     VI_PRINTF("Details actor lacp pdu: \n");
     452           0 :                     ret = get_port_states(msg_req, info.actor_state);
     453           0 :                     if (ret < 0)
     454           0 :                         RTE_LOG(ERR, VROUTER, "Failed to get stats for actor port: %d\n",
     455             :                                                port_id);
     456             : 
     457           0 :                     VI_PRINTF("Details partner lacp pdu: \n");
     458           0 :                     ret = get_port_states(msg_req, info.partner_state);
     459           0 :                     if (ret < 0)
     460           0 :                         RTE_LOG(ERR, VROUTER, "Failed to get stats for partner port=%d\n",
     461             :                                                port_id);
     462             :                 } else {
     463           0 :                     VI_PRINTF("Port id: %d slave id: %d Link status: DOWN\n\n", port_id, slave_id);
     464             :                 }
     465             :             }
     466             : 
     467           0 :             VI_PRINTF("LACP Packet Statistics:\n");
     468           0 :             VI_PRINTF("\t\t Tx \t Rx\n");
     469             : 
     470           0 :             for (i = 0; i < ethdev->ethdev_nb_slaves; i++) {
     471           0 :                 slave_id = ethdev->ethdev_slaves[i];
     472             : 
     473           0 :                 ret = rte_eth_dev_get_name_by_port(slave_id, name);
     474           0 :                 if (ret != 0) {
     475           0 :                     RTE_LOG(ERR, VROUTER, "%s: Error getting dev name id:%d\n",
     476             :                                             __func__, slave_id);
     477             :                 }
     478             : 
     479           0 :                 lacp_tx_cnt = rte_eth_bond_8023ad_lacp_tx_count(slave_id, 0);
     480             :                 if (lacp_tx_cnt < 0) {
     481             :                     RTE_LOG(ERR, VROUTER, "Failed to get lacp tx count  port=%d\n",
     482             :                                            port_id);
     483             :                     continue;
     484             :                 }
     485             : 
     486           0 :                 lacp_rx_cnt = rte_eth_bond_8023ad_lacp_rx_count(slave_id, 0);
     487             :                 if (lacp_rx_cnt < 0) {
     488             :                     RTE_LOG(ERR, VROUTER, "Failed to get lacp rx count  port=%d\n",
     489             :                                            port_id);
     490             :                     continue;
     491             :                 }
     492             : 
     493           0 :                 VI_PRINTF("%s\t%"PRId64"\t%"PRId64"\n", name, lacp_tx_cnt, lacp_rx_cnt);
     494             :             }
     495           0 :             VI_PRINTF("\n");
     496           0 :         } else if (strcmp(msg_req->inbuf, "conf") == 0) {
     497           0 :             ret = display_lacp_conf(msg_req, port_id);
     498             :         }
     499             :     }
     500           0 :     return 0;
     501             : }
     502             : 
     503             : static void
     504           3 : walk_cb(struct rte_mempool *mp, void *arg __rte_unused)
     505             : {
     506           3 :     vr_info_t *msg_req = (vr_info_t * ) arg;
     507           3 :     VR_INFO_DEC();
     508             : 
     509             :     /* redefining VR_INFO_FAILED to prevent VI_PRINTF
     510             :        to return non-void value */
     511             :     #undef VR_INFO_FAILED
     512             :     #define VR_INFO_FAILED
     513             : 
     514             :     /* redefining VR_INFO_MSG_TRUNC to prevent VI_PRINTF
     515             :        to return non-void value */
     516             :     #undef VR_INFO_MSG_TRUNC
     517             :     #define VR_INFO_MSG_TRUNC
     518             : 
     519           3 :     VI_PRINTF("%-20s\t", mp->name);
     520           3 :     VI_PRINTF("%d\t", mp->size);
     521           3 :     VI_PRINTF("%d\t", rte_mempool_in_use_count(mp));
     522           3 :     VI_PRINTF("%d\t\n", rte_mempool_avail_count(mp));
     523             : 
     524             :     #undef VR_INFO_FAILED
     525             :     #define VR_INFO_FAILED - 1
     526             : 
     527             :     #undef VR_INFO_MSG_TRUNC
     528             :     #define VR_INFO_MSG_TRUNC - 2
     529           3 :     return;
     530             : }
     531             : 
     532             : int
     533           1 : dpdk_info_get_mempool(VR_INFO_ARGS)
     534           1 : {
     535           1 :     int reqd_mempool = 0;
     536           1 :     struct rte_mempool *mp = NULL;
     537             :     struct rte_mempool_memhdr *memhdr;
     538           1 :     unsigned lcore_id = 0, common_count = 0, cache_count = 0, count = 0;
     539           1 :     size_t mem_len = 0;
     540           1 :     char col_names[] = "Name\t\t\tSize\tUsed\tAvailable";
     541             :     /* Adding 25 to extend the seperator a bit */
     542           1 :     int col_size = (sizeof(col_names) / sizeof(col_names[0])) + 25;
     543           1 :     char seperator[col_size];
     544             : 
     545           1 :     VR_INFO_BUF_INIT();
     546             : 
     547           1 :     if (strcmp(msg_req->inbuf, "all") == 0) {
     548           1 :         reqd_mempool = 1;
     549             :     }
     550           1 :     switch (reqd_mempool) {
     551           0 :     case 0:
     552           0 :         mp = rte_mempool_lookup(msg_req->inbuf);
     553           0 :         if (mp == NULL) {
     554           0 :             RTE_LOG(ERR, VROUTER, "Mempool name does not exists.\n");
     555           0 :             return -1;
     556             :         }
     557             : 
     558           0 :         VI_PRINTF("%s\n", mp->name);
     559           0 :         VI_PRINTF("flags = %x\n", mp->flags);
     560           0 :         VI_PRINTF("nb_mem_chunks = %u\n", mp->nb_mem_chunks);
     561           0 :         VI_PRINTF("size = %"
     562             :             PRIu32 "\n", mp->size);
     563           0 :         VI_PRINTF("populated_size = %"
     564             :             PRIu32 "\n", mp->populated_size);
     565           0 :         VI_PRINTF("header_size = %"
     566             :             PRIu32 "\n", mp->header_size);
     567           0 :         VI_PRINTF("elt_size = %"
     568             :             PRIu32 "\n", mp->elt_size);
     569           0 :         VI_PRINTF("trailer_size = %"
     570             :             PRIu32 "\n", mp->trailer_size);
     571           0 :         VI_PRINTF("total_obj_size = %"
     572             :             PRIu32 "\n",
     573             :             mp->header_size + mp->elt_size + mp->trailer_size);
     574           0 :         VI_PRINTF("private_data_size = %"
     575             :             PRIu32 "\n", mp->private_data_size);
     576             : 
     577           0 :         STAILQ_FOREACH(memhdr, &mp->mem_list, next)
     578           0 :         mem_len += memhdr->len;
     579           0 :         if (mem_len != 0) {
     580           0 :             VI_PRINTF("avg bytes/object = %#Lf\n",
     581             :                 (long double) mem_len / mp->size);
     582             :         }
     583             : 
     584           0 :         VI_PRINTF("Internal cache infos:\n");
     585           0 :         VI_PRINTF("\tcache_size=%"
     586             :             PRIu32 "\n", mp->cache_size);
     587             : 
     588           0 :         if (mp->cache_size == 0) {
     589           0 :             count = 0;
     590             :         } else {
     591           0 :             for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
     592           0 :                 cache_count = mp->local_cache[lcore_id].len;
     593           0 :                 if (cache_count != 0) {
     594           0 :                     VI_PRINTF("\tcache_count[%u]=%"
     595             :                         PRIu32 "\n", lcore_id, cache_count);
     596             :                 }
     597           0 :                 count += cache_count;
     598             :             }
     599             :         }
     600           0 :         VI_PRINTF("total_cache_count=%u\n", count);
     601           0 :         common_count = rte_mempool_ops_get_count(mp);
     602           0 :         if ((cache_count + common_count) > mp->size) {
     603           0 :             common_count = mp->size - cache_count;
     604             :         }
     605           0 :         VI_PRINTF("common_pool_count=%u\n\n", common_count);
     606           0 :         break;
     607             : 
     608           1 :     case 1:
     609           1 :         memset(seperator, '-', col_size);
     610           1 :         seperator[col_size-1] = '\0';
     611           1 :         VI_PRINTF("%s\n", seperator);
     612           1 :         VI_PRINTF("%s\n", col_names);
     613           1 :         VI_PRINTF("%s\n", seperator);
     614           1 :         rte_mempool_walk(walk_cb, msg_req);
     615           1 :         VI_PRINTF("\n\n");
     616           1 :         break;
     617             : 
     618             :     }
     619           1 :     return 0;
     620             : }
     621             : 
     622             : static int
     623           0 : display_eth_stats(VR_INFO_ARGS, struct rte_eth_stats eth_stats)
     624             : {
     625             : 
     626           0 :     VR_INFO_DEC();
     627             :     int i, queue_size;
     628             :     char seperator[SEPERATOR];
     629             : 
     630           0 :     VI_PRINTF("RX Device Packets:%"
     631             :         PRId64 ", Bytes:%"
     632             :         PRId64 ", Errors:%"
     633             :         PRId64 ", Nombufs:%"
     634             :         PRId64 "\n", eth_stats.ipackets,
     635             :         eth_stats.ibytes, eth_stats.ierrors, eth_stats.rx_nombuf);
     636           0 :     VI_PRINTF("Dropped RX Packets:%"
     637             :         PRId64 "\n", eth_stats.imissed);
     638           0 :     VI_PRINTF("TX Device Packets:%"
     639             :         PRId64 ", Bytes:%"
     640             :         PRId64 ", Errors:%"
     641             :         PRId64 "\n", eth_stats.opackets, eth_stats.obytes, eth_stats.oerrors);
     642             : 
     643           0 :     queue_size = sizeof(eth_stats.q_ipackets) / sizeof(eth_stats.q_ipackets[0]);
     644           0 :     memset(seperator, '-', SEPERATOR);
     645           0 :     seperator[SEPERATOR-1] = '\0';
     646             : 
     647           0 :     VI_PRINTF("%s", "Queue Rx:");
     648           0 :     for (i = 0; i < queue_size; i++) {
     649           0 :         if (eth_stats.q_ipackets[i] != 0) {
     650           0 :             VI_PRINTF(" [%d]", i);
     651           0 :             VI_PRINTF("%"
     652             :                 PRId64 " ", eth_stats.q_ipackets[i]);
     653             :         }
     654             :     }
     655           0 :     VI_PRINTF("\n");
     656             : 
     657           0 :     VI_PRINTF("%s", "      Tx:");
     658           0 :     for (i = 0; i < queue_size; i++) {
     659           0 :         if (eth_stats.q_opackets[i] != 0) {
     660           0 :             VI_PRINTF(" [%d]", i);
     661           0 :             VI_PRINTF("%"
     662             :                 PRId64 " ", eth_stats.q_opackets[i]);
     663             :         }
     664             :     }
     665           0 :     VI_PRINTF("\n");
     666             : 
     667           0 :     VI_PRINTF("%s", "      Rx Bytes:");
     668           0 :     for (i = 0; i < queue_size; i++) {
     669           0 :         if (eth_stats.q_ibytes[i] != 0) {
     670           0 :             VI_PRINTF(" [%d]", i);
     671           0 :             VI_PRINTF("%"
     672             :                 PRId64 " ", eth_stats.q_ibytes[i]);
     673             :         }
     674             :     }
     675           0 :     VI_PRINTF("\n");
     676             : 
     677           0 :     VI_PRINTF("%s", "      Tx Bytes:");
     678           0 :     for (i = 0; i < queue_size; i++) {
     679           0 :         if (eth_stats.q_obytes[i] != 0) {
     680           0 :             VI_PRINTF(" [%d]", i);
     681           0 :             VI_PRINTF("%"
     682             :                 PRId64 " ", eth_stats.q_obytes[i]);
     683             :         }
     684             :     }
     685           0 :     VI_PRINTF("\n");
     686             : 
     687           0 :     VI_PRINTF("%s", "      Errors:");
     688           0 :     for (i = 0; i < queue_size; i++) {
     689           0 :         if (eth_stats.q_errors[i] != 0) {
     690           0 :             VI_PRINTF(" [%d]", i);
     691           0 :             VI_PRINTF("%"
     692             :                 PRId64 " ", eth_stats.q_errors[i]);
     693             :         }
     694             :     }
     695           0 :     VI_PRINTF("\n");
     696           0 :     VI_PRINTF("%s\n\n", seperator);
     697           0 :     return 0;
     698             : }
     699             : 
     700             : int
     701           0 : dpdk_info_get_stats(VR_INFO_ARGS)
     702             : {
     703             : 
     704           0 :     uint16_t port_id, slave_id = 0;
     705           0 :     int i, j, ret = 0;
     706             :     struct rte_eth_stats eth_stats;
     707             :     struct vr_dpdk_ethdev *ethdev;
     708             :     struct vr_dpdk_bond_port_list port_list;
     709           0 :     char name[VR_INTERFACE_NAME_LEN] = "";
     710             : 
     711           0 :     VR_INFO_BUF_INIT();
     712             : 
     713             :     /* msg req buf is not eth, return */
     714           0 :     if (strcmp(msg_req->inbuf, "eth")) {
     715           0 :         RTE_LOG(ERR, VROUTER, "Invalid argument.\n");
     716           0 :         return -1;
     717             :     }
     718             : 
     719             :     /* Get the port_id list for master, Incase of non-bond devices,
     720             :        it return here.
     721             :      */
     722           0 :     if (!dpdk_find_bond_port_id_list(&port_list)) {
     723           0 :         RTE_LOG(ERR, VROUTER, "%s: Port Id is invalid\n", __func__);
     724           0 :         return -1;
     725             :     }
     726             : 
     727           0 :     VI_PRINTF("No. of bond ids: %d\n", port_list.intf_count);
     728           0 :     for (j = 0; j < port_list.intf_count; j++) {
     729           0 :         port_id = port_list.intf_list[j];
     730             :         /* Get the ethdev for master port. */
     731           0 :         ethdev = &vr_dpdk.ethdevs[port_id];
     732           0 :         if (ethdev == NULL ||
     733           0 :             ethdev->ethdev_ptr == NULL) {
     734           0 :             RTE_LOG(ERR, VROUTER, "%s: Ethdev not available port id: %d\n",
     735             :                                   __func__, port_id);
     736           0 :             continue;
     737             :         }
     738             : 
     739           0 :         if (rte_eth_stats_get(port_id, &eth_stats) != 0) {
     740           0 :             continue;
     741             :         }
     742             : 
     743           0 :         rte_eth_dev_get_name_by_port(port_id, name);
     744           0 :         if (strcmp(msg_req->inbuf, "eth") == 0) {
     745           0 :             VI_PRINTF("Master %s Info: No. of slaves: %d\n",
     746             :                        name, ethdev->ethdev_nb_slaves);
     747           0 :             VI_PRINTF("============================================\n");
     748           0 :             ret = display_eth_stats(msg_req, eth_stats);
     749             : 
     750             :             /* Displaying slave stats */
     751           0 :             for (i = 0; i < ethdev->ethdev_nb_slaves; i++) {
     752           0 :                 slave_id = ethdev->ethdev_slaves[i];
     753           0 :                 ret = rte_eth_dev_get_name_by_port(slave_id, name);
     754           0 :                 if (ret != 0) {
     755           0 :                     RTE_LOG(ERR, VROUTER, "%s: Error getting dev name "
     756             :                             "port: %d slave: %d\n", __func__, port_id, slave_id);
     757           0 :                     continue;
     758             :                 }
     759           0 :                 VI_PRINTF("Slave Info(%s): \n", name);
     760           0 :                 if (rte_eth_stats_get(slave_id, &eth_stats) != 0) {
     761           0 :                     RTE_LOG(ERR, VROUTER, "%s: Error getting interface stats "
     762             :                             "port: %d slave: %d\n", __func__, port_id, slave_id);
     763           0 :                     continue;
     764             :                 }
     765           0 :                 ret = display_eth_stats(msg_req, eth_stats);
     766             :             }
     767             :         }
     768             :     }
     769             : 
     770           0 :     return 0;
     771             : }
     772             : 
     773             : static int
     774           0 : __display_xstats(VR_INFO_ARGS, uint16_t port_id, int xstats_count, bool is_all,
     775             :         uint64_t *values, struct rte_eth_xstat_name *xstats_names)
     776           0 : {
     777             : 
     778           0 :     VR_INFO_DEC();
     779           0 :     int ret, i, segment_lookup[VR_DPDK_BOND_MAX_SLAVES][xstats_count],
     780           0 :         rpi = 0, rbi = 0, tpi = 0, tbi = 0, ei = 0, oth = 0;
     781             :     char seperator[SEPERATOR];
     782           0 :     memset(seperator, '-', SEPERATOR);
     783           0 :     seperator[SEPERATOR-1] = '\0';
     784             : 
     785           0 :     if (xstats_count != rte_eth_xstats_get_names_by_id(port_id, xstats_names,
     786             :         xstats_count, NULL)) {
     787           0 :         RTE_LOG(ERR, VROUTER, "Cannot get xstat names\n");
     788           0 :         return VR_INFO_FAILED;
     789             :     }
     790             : 
     791           0 :     ret = rte_eth_xstats_get_by_id(port_id, NULL, values, xstats_count);
     792           0 :     if (ret < 0 || ret > xstats_count) {
     793           0 :         RTE_LOG(ERR, VROUTER, "Cannot get xstats\n");
     794           0 :         return VR_INFO_FAILED;
     795             :     }
     796             :     /* Adding the indices of respective segments in segment_lookup array */
     797           0 :     for (i = 0; i < xstats_count; i++) {
     798           0 :         if (strstr(xstats_names[i].name, "rx") &&
     799           0 :             strstr(xstats_names[i].name, "packets")) {
     800           0 :             segment_lookup[RX_PACKETS][rpi++] = i;
     801           0 :         } else if (strstr(xstats_names[i].name, "tx") &&
     802           0 :               strstr(xstats_names[i].name, "packets")) {
     803           0 :             segment_lookup[TX_PACKETS][tpi++] = i;
     804           0 :         } else if (strstr(xstats_names[i].name, "rx") &&
     805           0 :               strstr(xstats_names[i].name, "bytes")) {
     806           0 :             segment_lookup[RX_BYTES][rbi++] = i;
     807           0 :         } else if (strstr(xstats_names[i].name, "tx") &&
     808           0 :               strstr(xstats_names[i].name, "bytes")) {
     809           0 :             segment_lookup[TX_BYTES][tbi++] = i;
     810           0 :         } else if (strstr(xstats_names[i].name, "errors")) {
     811           0 :             segment_lookup[ERRORS][ei++] = i;
     812             :         } else {
     813           0 :             segment_lookup[OTHERS][oth++] = i;
     814             :         }
     815             :     }
     816             : 
     817             :     /* Printing xstats name and value segment-wise */
     818           0 :     VI_PRINTF("Rx Packets: \n");
     819           0 :     for (i = 0; i < rpi - 1; i++) {
     820           0 :         if (values[segment_lookup[RX_PACKETS][i]] != 0 || is_all) {
     821           0 :             VI_PRINTF("\t%s: %"PRIu64 "\n",
     822             :                 xstats_names[segment_lookup[RX_PACKETS][i]].name,
     823             :                 values[segment_lookup[RX_PACKETS][i]]);
     824             :         }
     825             :     }
     826           0 :     VI_PRINTF("Tx Packets: \n");
     827           0 :     for (i = 0; i < tpi - 1; i++) {
     828           0 :         if (values[segment_lookup[TX_PACKETS][i]] != 0 || is_all) {
     829           0 :             VI_PRINTF("\t%s: %"PRIu64 "\n",
     830             :                 xstats_names[segment_lookup[TX_PACKETS][i]].name,
     831             :                 values[segment_lookup[TX_PACKETS][i]]);
     832             :         }
     833             :     }
     834           0 :     VI_PRINTF("Rx Bytes: \n");
     835           0 :     for (i = 0; i < rbi - 1; i++) {
     836           0 :         if (values[segment_lookup[RX_BYTES][i]] != 0 || is_all) {
     837           0 :             VI_PRINTF("\t%s: %"PRIu64 "\n",
     838             :                 xstats_names[segment_lookup[RX_BYTES][i]].name,
     839             :                 values[segment_lookup[RX_BYTES][i]]);
     840             :         }
     841             :     }
     842           0 :     VI_PRINTF("Tx Bytes: \n");
     843           0 :     for (i = 0; i < tbi - 1; i++) {
     844           0 :         if (values[segment_lookup[TX_BYTES][i]] != 0 || is_all) {
     845           0 :             VI_PRINTF("\t%s: %"PRIu64 "\n",
     846             :                 xstats_names[segment_lookup[TX_BYTES][i]].name,
     847             :                 values[segment_lookup[TX_BYTES][i]]);
     848             :         }
     849             :     }
     850           0 :     VI_PRINTF("Errors: \n");
     851           0 :     for (i = 0; i < ei - 1; i++) {
     852           0 :         if (values[segment_lookup[ERRORS][i]] != 0 || is_all) {
     853           0 :             VI_PRINTF("\t%s: %"PRIu64 "\n",
     854             :                 xstats_names[segment_lookup[ERRORS][i]].name,
     855             :                 values[segment_lookup[ERRORS][i]]);
     856             :         }
     857             :     }
     858           0 :     VI_PRINTF("Others: \n");
     859           0 :     for (i = 0; i < oth - 1; i++) {
     860           0 :         if (values[segment_lookup[OTHERS][i]] != 0 || is_all) {
     861           0 :             VI_PRINTF("\t%s: %"PRIu64 "\n",
     862             :                 xstats_names[segment_lookup[OTHERS][i]].name,
     863             :                 values[segment_lookup[OTHERS][i]]);
     864             :         }
     865             :     }
     866             : 
     867           0 :     VI_PRINTF("%s\n\n", seperator);
     868           0 :     return 0;
     869             : }
     870             : 
     871             : static int
     872           0 : display_xstats(VR_INFO_ARGS, uint16_t port_id, int xstats_count, bool is_all)
     873             : {
     874           0 :     struct rte_eth_xstat_name *xstats_names = NULL;
     875           0 :     uint64_t *values = NULL;
     876           0 :     int ret = 0;
     877             : 
     878           0 :     values = (uint64_t *)vr_zalloc(
     879             :             sizeof( *values) * xstats_count, VR_INFO_REQ_OBJECT);
     880           0 :     if (values == NULL) {
     881           0 :         RTE_LOG(ERR, VROUTER, "Cannot allocate memory for xstats\n");
     882           0 :         ret = VR_INFO_FAILED;
     883           0 :         goto exit;
     884             :     }
     885             : 
     886           0 :     xstats_names = (struct rte_eth_xstat_name *)vr_zalloc(
     887             :             sizeof(struct rte_eth_xstat_name) * xstats_count, VR_INFO_REQ_OBJECT);
     888           0 :     if (xstats_names == NULL) {
     889           0 :         RTE_LOG(ERR, VROUTER, "Cannot allocate memory for xstat names\n");
     890           0 :         ret = VR_INFO_FAILED;
     891           0 :         goto exit;
     892             :     }
     893             : 
     894           0 :     ret = __display_xstats(msg_req, port_id, xstats_count, is_all, values,
     895             :             xstats_names);
     896             : 
     897           0 : exit:
     898           0 :     if (values) {
     899           0 :         vr_free(values, VR_INFO_REQ_OBJECT);
     900           0 :         values = NULL;
     901             :     }
     902           0 :     if (xstats_names) {
     903           0 :         vr_free(xstats_names, VR_INFO_REQ_OBJECT);
     904           0 :         xstats_names = NULL;
     905             :     }
     906             : 
     907           0 :     return ret;
     908             : }
     909             : 
     910             : int
     911           0 : dpdk_info_get_xstats(VR_INFO_ARGS)
     912             : {
     913             : 
     914           0 :     uint16_t port_id, slave_id = 0;
     915           0 :     int i, j, reqd_interface, ret = 0, slave = 0, xstats_count = -1;
     916           0 :     char name[VR_INTERFACE_NAME_LEN] = "";
     917           0 :     struct vrouter *router = vrouter_get(0);
     918           0 :     struct vr_dpdk_ethdev *ethdev = NULL;
     919             :     struct vr_dpdk_bond_port_list port_list;
     920           0 :     bool is_all = false;
     921             : 
     922           0 :     VR_INFO_BUF_INIT();
     923             : 
     924           0 :     is_all = !strcmp(msg_req->inbuf, "all");
     925             : 
     926             :     /* Get the port_id list for master, Incase of non-bond devices,
     927             :        it return here. */
     928           0 :     if (dpdk_find_bond_port_id_list(&port_list)) {
     929           0 :         VI_PRINTF("No. of bond ids: %d\n", port_list.intf_count);
     930           0 :         for (j = 0; j < port_list.intf_count; j++) {
     931           0 :             port_id = port_list.intf_list[j];
     932             :             /* Get the ethdev for master port. */
     933           0 :             ethdev = &vr_dpdk.ethdevs[port_id];
     934           0 :             if (ethdev->ethdev_ptr == NULL) {
     935           0 :                 RTE_LOG(ERR, VROUTER, "Ethdev not available for port=%d\n", port_id);
     936           0 :                 continue;
     937             :             }
     938             : 
     939           0 :             rte_eth_dev_get_name_by_port(port_id, name);
     940           0 :             VI_PRINTF("=======================================\n");
     941           0 :             VI_PRINTF("|| Bond Interface(%d): %s ||\n", port_id, name);
     942           0 :             VI_PRINTF("=======================================\n");
     943             : 
     944           0 :             if (!strcmp(msg_req->inbuf, "") || is_all) {
     945           0 :                 reqd_interface = 0;
     946           0 :             } else if (!strcmp(msg_req->inbuf, "0") ||
     947           0 :                     (atoi(msg_req->inbuf) > 0 &&
     948           0 :                      atoi(msg_req->inbuf) <= ethdev->ethdev_nb_slaves)) {
     949           0 :                 reqd_interface = 1;
     950             :             } else {
     951           0 :                 VI_PRINTF("There are only %d slaves available.\n\n",
     952             :                         ethdev->ethdev_nb_slaves);
     953           0 :                 continue;
     954             :             }
     955             : 
     956           0 :             xstats_count = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL);
     957           0 :             if (xstats_count < 0) {
     958           0 :                 RTE_LOG(ERR, VROUTER, "Cannot get xstats count port=%d\n", port_id);
     959           0 :                 continue;
     960             :             }
     961             : 
     962           0 :             switch (reqd_interface) {
     963           0 :                 case 0:
     964           0 :                     VI_PRINTF("Master Info: \n");
     965           0 :                     ret = display_xstats(msg_req, port_id, xstats_count, is_all);
     966           0 :                     if (ret < 0) {
     967           0 :                         RTE_LOG(ERR, VROUTER, "Failed to display xstats port=%d\n", port_id);
     968           0 :                         continue;
     969             :                     }
     970             : 
     971             :                     /* Displaying slave stats */
     972           0 :                     for (i = 0; i < ethdev->ethdev_nb_slaves; i++) {
     973           0 :                         slave_id = ethdev->ethdev_slaves[i];
     974           0 :                         ret = rte_eth_dev_get_name_by_port(slave_id, name);
     975           0 :                         if (ret != 0) {
     976           0 :                             RTE_LOG(ERR, VROUTER, "%s: Error getting dev  name "
     977             :                                     "port=%d slave=%d\n", __func__, port_id, slave_id);
     978           0 :                             continue;
     979             :                         }
     980           0 :                         VI_PRINTF("Slave Info(%d):%s \n", i, name);
     981             : 
     982           0 :                         xstats_count = rte_eth_xstats_get_names_by_id(slave_id, NULL,
     983             :                                 0, NULL);
     984           0 :                         if (xstats_count < 0) {
     985           0 :                             RTE_LOG(ERR, VROUTER, "Cannot get xstats count "
     986             :                                     "port=%d slave=%d\n", port_id, slave_id);
     987           0 :                             continue;
     988             :                         }
     989           0 :                         ret = display_xstats(msg_req, slave_id, xstats_count, is_all);
     990           0 :                         if (ret < 0) {
     991           0 :                             RTE_LOG(ERR, VROUTER, "Failed to display xstats "
     992             :                                     "port=%d slave=%d\n", port_id, slave_id);
     993           0 :                             continue;
     994             :                         }
     995             :                     }
     996           0 :                     break;
     997           0 :                 case 1:
     998           0 :                     if (!strcmp(msg_req->inbuf, "0")) {
     999           0 :                         VI_PRINTF("Master Info: \n");
    1000           0 :                         ret = display_xstats(msg_req, port_id, xstats_count, is_all);
    1001           0 :                         if (ret < 0)
    1002           0 :                             continue;
    1003             : 
    1004             :                     } else {
    1005           0 :                         slave = atoi(msg_req->inbuf) - 1;
    1006           0 :                         slave_id = ethdev->ethdev_slaves[slave];
    1007           0 :                         ret = rte_eth_dev_get_name_by_port(slave_id, name);
    1008           0 :                         if (ret != 0) {
    1009           0 :                             RTE_LOG(ERR, VROUTER, "%s: Error getting bond interface namei "
    1010             :                                     "port=%d slave=%d\n", __func__, port_id, slave_id);
    1011           0 :                             continue;
    1012             :                         }
    1013           0 :                         VI_PRINTF("Slave Info(%d):%s \n", slave, name);
    1014           0 :                         xstats_count = rte_eth_xstats_get_names_by_id(slave_id, NULL,
    1015             :                                 0, NULL);
    1016           0 :                         if (xstats_count < 0) {
    1017           0 :                             RTE_LOG(ERR, VROUTER, "Cannot get xstats count "
    1018             :                                     "port=%d slave=%d\n", port_id, slave_id);
    1019           0 :                             continue;
    1020             :                         }
    1021           0 :                         ret = display_xstats(msg_req, slave_id, xstats_count, is_all);
    1022           0 :                         if (ret < 0)
    1023           0 :                             continue;
    1024             :                     }
    1025           0 :                     break;
    1026             :             }
    1027             :         }
    1028             :     }else {
    1029             :         /* if bond is not configured */
    1030           0 :         if (strcmp(msg_req->inbuf, "") == 0 || is_all) {
    1031           0 :             if (router->vr_eth_if[0]) {
    1032           0 :                 ethdev = (struct vr_dpdk_ethdev* ) router->vr_eth_if[0]->vif_os;
    1033             :             }
    1034           0 :             if (!ethdev) {
    1035           0 :                 RTE_LOG(ERR, VROUTER, "%s: ethdev null\n", __func__);
    1036           0 :                 return -1;
    1037             :             }
    1038             : 
    1039           0 :             port_id = ethdev->ethdev_port_id;
    1040           0 :             xstats_count = rte_eth_xstats_get_names_by_id(port_id, NULL,
    1041             :                                                             0, NULL);
    1042           0 :             if (xstats_count < 0) {
    1043           0 :                 RTE_LOG(ERR, VROUTER, "Cannot get xstats count\n");
    1044           0 :                 return -1;
    1045             :             }
    1046             : 
    1047           0 :             ret = display_xstats(msg_req, port_id, xstats_count, is_all);
    1048           0 :             if (ret < 0)
    1049           0 :                 goto err;
    1050             : 
    1051             :         } else {
    1052           0 :             RTE_LOG(ERR, VROUTER, "Invalid argument.\n");
    1053           0 :             return -1;
    1054             :         }
    1055             :     }
    1056             : 
    1057           0 :     return 0;
    1058           0 : err:
    1059           0 :     return ret;
    1060             : }
    1061             : 
    1062             : int
    1063           0 : dpdk_info_get_lcore(VR_INFO_ARGS)
    1064             : {
    1065             :     struct vr_dpdk_queue *rx_queue;
    1066             :     struct vr_dpdk_lcore *lcore;
    1067             :     unsigned char *name;
    1068             :     int i;
    1069             : 
    1070           0 :     VR_INFO_BUF_INIT();
    1071             : 
    1072           0 :     VI_PRINTF("No. of forwarding lcores: %d \n\n", vr_dpdk.nb_fwd_lcores);
    1073             : 
    1074           0 :     for (i = 0; i < vr_dpdk.nb_fwd_lcores; i++) {
    1075           0 :         VI_PRINTF("Lcore %d: \n",  (VR_DPDK_FWD_LCORE_ID + i));
    1076           0 :         lcore = vr_dpdk.lcores[VR_DPDK_FWD_LCORE_ID + i];
    1077           0 :         SLIST_FOREACH(rx_queue, &lcore->lcore_rx_head, q_next) {
    1078           0 :             name = rx_queue->q_vif->vif_name;
    1079           0 :             VI_PRINTF("\tInterface: %-20s", name);
    1080           0 :             VI_PRINTF("Queue ID: %"
    1081             :                 PRId16 " \n", rx_queue->vring_queue_id);
    1082             :         }
    1083           0 :         VI_PRINTF("\n");
    1084             :     }
    1085             : 
    1086           0 :     return 0;
    1087             : }
    1088             : 
    1089             : int
    1090           0 : dpdk_info_get_app(VR_INFO_ARGS)
    1091             : {
    1092             : 
    1093             :     uint16_t port_id;
    1094           0 :     struct vr_dpdk_ethdev *ethdev = NULL;
    1095             :     struct rte_eth_dev_info dev_info;
    1096           0 :     struct vr_dpdk_tapdev *tapdev = vr_dpdk.tapdevs;
    1097             :     struct vr_dpdk_bond_port_list port_list;
    1098             :     size_t soff;
    1099           0 :     struct vrouter *router = vrouter_get(0);
    1100           0 :     int i, j = 0, k = 0;
    1101             :     struct vr_interface *vif;
    1102           0 :     bool monitoring_intf = false, sriov_flag = false;
    1103           0 :     char name[VR_INTERFACE_NAME_LEN] = "";
    1104             : 
    1105           0 :     VR_INFO_BUF_INIT();
    1106             : 
    1107           0 :     VI_PRINTF("No. of lcores: %d \n", vr_num_cpus);
    1108           0 :     VI_PRINTF("No. of forwarding lcores: %d \n", vr_dpdk.nb_fwd_lcores);
    1109             : 
    1110             :     /* Get the port_id list for master, Incase of non-bond devices, */
    1111           0 :     if (!dpdk_find_bond_port_id_list(&port_list)) {
    1112           0 :         RTE_LOG(ERR, VROUTER, "%s: Port Id list is invalid\n", __func__);
    1113           0 :         return -1;
    1114             :     }
    1115             : 
    1116             :     /* Display vlan information */
    1117           0 :     if (vr_dpdk.vlan_vif){
    1118           0 :         VI_PRINTF("Vlan vif: %s \n", vr_dpdk.vlan_vif->vif_name);
    1119           0 :         VI_PRINTF("Vlan name: %s \n", vr_dpdk.vlan_name);
    1120           0 :         VI_PRINTF("Vlan tag: %d \n", vr_dpdk.vlan_tag);
    1121             :     }
    1122             : 
    1123           0 :     VI_PRINTF("No. of bond id available: %d\n", port_list.intf_count);
    1124           0 :     for (j = 0; j < port_list.intf_count ; j++) {
    1125           0 :         port_id = port_list.intf_list[j];
    1126           0 :         ethdev = &vr_dpdk.ethdevs[port_id];
    1127           0 :         if (ethdev == NULL ||
    1128           0 :             ethdev->ethdev_ptr == NULL) {
    1129           0 :             RTE_LOG(ERR, VROUTER, "%s: Ethdev not available\n", __func__);
    1130           0 :             continue;
    1131             :         }
    1132             : 
    1133             :         /* Display Ethdev information */
    1134           0 :         if (ethdev->ethdev_ptr) {
    1135           0 :             rte_eth_dev_get_name_by_port(port_id, name);
    1136           0 :             rte_eth_dev_info_get(port_id, &dev_info);
    1137           0 :             VI_PRINTF("Ethdev (Master: %s):\n", name);
    1138           0 :             VI_PRINTF("================================\n");
    1139           0 :             VI_PRINTF("\tMax rx queues: %"PRIu16"\n", dev_info.max_rx_queues);
    1140           0 :             VI_PRINTF("\tMax tx queues: %"PRIu16"\n", dev_info.max_tx_queues);
    1141           0 :             VI_PRINTF("\tEthdev nb rx queues: %"PRIu16"\n",
    1142             :                     ethdev->ethdev_nb_rx_queues);
    1143           0 :             VI_PRINTF("\tEthdev nb tx queues: %"PRIu16"\n",
    1144             :                     ethdev->ethdev_nb_tx_queues);
    1145           0 :             VI_PRINTF("\tEthdev nb rss queues: %"PRIu16"\n",
    1146             :                     ethdev->ethdev_nb_rss_queues);
    1147           0 :             VI_PRINTF("\tEthdev reta size: %"PRIu16"\n", ethdev->ethdev_reta_size);
    1148           0 :             VI_PRINTF("\tEthdev port id: %"PRIu16"\n", ethdev->ethdev_port_id);
    1149           0 :             VI_PRINTF("\tEthdev nb slaves: %d \n", ethdev->ethdev_nb_slaves);
    1150           0 :             VI_PRINTF("\tEthdev slaves: ");
    1151           0 :             for (i = 0; i < VR_DPDK_BOND_MAX_SLAVES; i++){
    1152           0 :                 VI_PRINTF("%"PRIu16 " ", ethdev->ethdev_slaves[i]);
    1153             :             }
    1154           0 :             VI_PRINTF("\n\n");
    1155             :         }
    1156             : 
    1157           0 :         for (i = 0; i < ethdev->ethdev_nb_slaves; i++) {
    1158           0 :             VI_PRINTF("Ethdev (Slave %d): %s\n", i, rte_eth_devices[i].data->name);
    1159           0 :             VI_PRINTF("\tNb rx queues: %"PRIu16"\n",
    1160             :                     rte_eth_devices[i].data->nb_rx_queues);
    1161           0 :             VI_PRINTF("\tNb tx queues: %"PRIu16"\n",
    1162             :                     rte_eth_devices[i].data->nb_tx_queues);
    1163           0 :             VI_PRINTF("\tEthdev reta size: %"PRIu16"\n\n", dev_info.reta_size);
    1164             :         }
    1165             :     }
    1166             : 
    1167             :     /* Display Tapdev information */
    1168           0 :     if(tapdev) {
    1169           0 :         VI_PRINTF("Tapdev:\n");
    1170           0 :         while (tapdev[k].tapdev_fd){
    1171           0 :             VI_PRINTF("\tfd: %d", tapdev[k].tapdev_fd);
    1172           0 :             if(tapdev[k].tapdev_vif) {
    1173           0 :                 VI_PRINTF("\tvif name: %s \n", tapdev[k].tapdev_vif->vif_name);
    1174             :             }
    1175           0 :             k++;
    1176             :         }
    1177             :     }
    1178           0 :     VI_PRINTF("\n");
    1179             : 
    1180             :     /* Display Monitoring interfaces */
    1181           0 :     for (i = 0; i < router->vr_max_interfaces; i++){
    1182           0 :          if (vr_dpdk.monitorings[i] != 0 &&
    1183           0 :                  vr_dpdk.monitorings[i] != VR_MAX_INTERFACES){
    1184           0 :              if (!monitoring_intf){
    1185           0 :                  VI_PRINTF("Monitorings:\n");
    1186           0 :                  monitoring_intf = true;
    1187             :              }
    1188           0 :              vif = router->vr_interfaces[i];
    1189           0 :              VI_PRINTF("\t%s\n", vif->vif_name);
    1190             :          }
    1191             :     }
    1192             : 
    1193             :     /* Display SRIOV information */
    1194           0 :     VR_DPDK_RTE_ETH_FOREACH_DEV(i){
    1195           0 :          rte_eth_dev_info_get(i, &dev_info);
    1196             :          /* Check PMD name suffix to detect SR-IOV virtual function. */
    1197           0 :          soff = strlen(dev_info.driver_name) - sizeof(VR_DPDK_VF_PMD_SFX) + 1;
    1198           0 :          if (soff > 0 &&
    1199           0 :                strncmp(dev_info.driver_name + soff, VR_DPDK_VF_PMD_SFX,
    1200             :                sizeof(VR_DPDK_VF_PMD_SFX)) == 0){
    1201           0 :              if (dev_info.max_tx_queues < vr_dpdk.nb_fwd_lcores
    1202             :                     /* We also need 2 TX queues for Netlink and Packet lcores. */
    1203             :                     + VR_DPDK_FWD_LCORE_ID - VR_DPDK_PACKET_LCORE_ID) {
    1204           0 :                  if (!sriov_flag){
    1205           0 :                      VI_PRINTF("Sriov:\n");
    1206           0 :                      sriov_flag = true;
    1207             :                  }
    1208           0 :                  VI_PRINTF("\tLcore: %d", VR_DPDK_FWD_LCORE_ID);
    1209           0 :                  VI_PRINTF("\tEthdev port id: %d", i);
    1210           0 :                  VI_PRINTF("\tDriver Name: %s\n", dev_info.driver_name);
    1211           0 :                 break;
    1212             :              }
    1213             :          }
    1214             :     }
    1215             : 
    1216           0 :     VI_PRINTF("\n");
    1217             : 
    1218           0 :     return 0;
    1219             : }
    1220             : 
    1221             : int
    1222           0 : dpdk_info_get_ddp(VR_INFO_ARGS)
    1223             : {
    1224             :     struct rte_pmd_i40e_profile_list *p_list;
    1225             :     struct rte_pmd_i40e_profile_info *p_info;
    1226             :     uint32_t p_num, size, i;
    1227             :     int ret;
    1228           0 :     uint16_t port_id = 0;
    1229           0 :     VR_INFO_BUF_INIT();
    1230             : 
    1231           0 :     if (strcmp(msg_req->inbuf, "list") != 0) {
    1232           0 :         return -1;
    1233             :     }
    1234             : 
    1235           0 :     size = I40E_MAX_PROFILE_NUM * sizeof(struct rte_pmd_i40e_profile_list);
    1236             : 
    1237           0 :     p_list = (struct rte_pmd_i40e_profile_list *)vr_zalloc(size,
    1238             :                         VR_INFO_REQ_OBJECT);
    1239           0 :     if(!p_list) {
    1240           0 :         RTE_LOG(ERR, VROUTER, "%s: Memory allocation failed\n", __func__);
    1241           0 :         return -1;
    1242             :     }
    1243             : 
    1244           0 :     ret = rte_pmd_i40e_get_ddp_list(port_id, (uint8_t *)p_list, size);
    1245             : 
    1246           0 :     if (!ret) {
    1247           0 :         p_num = p_list->p_count;
    1248           0 :         VI_PRINTF("Profile count is: %d\n\n", p_num);
    1249           0 :         if(p_num == 0) {
    1250           0 :             VI_PRINTF("DDP profile is not enabled \n\n");
    1251             :         }
    1252             : 
    1253           0 :         for (i = 0; i < p_num; i++) {
    1254           0 :                 p_info = &p_list->p_info[i];
    1255           0 :                 VI_PRINTF("Profile %d:\n", i);
    1256           0 :                 VI_PRINTF("Track id:     0x%x\n", p_info->track_id);
    1257           0 :                 VI_PRINTF("Version:      %d.%d.%d.%d\n",
    1258             :                        p_info->version.major,
    1259             :                        p_info->version.minor,
    1260             :                        p_info->version.update,
    1261             :                        p_info->version.draft);
    1262           0 :                 VI_PRINTF("Profile name: %s\n\n", p_info->name);
    1263             :         }
    1264             :     }
    1265             : 
    1266           0 :     if(p_list)
    1267           0 :         vr_free(p_list, VR_INFO_REQ_OBJECT);
    1268             : 
    1269           0 :     if(ret == -ENOTSUP) {
    1270           0 :         VI_PRINTF("DDP works only on X710 NIC series \n\n");
    1271           0 :     } else if (ret < 0) {
    1272           0 :         VI_PRINTF("Failed to get ddp list, return value is %d \n\n", ret);
    1273             :     }
    1274             : 
    1275           0 :     return 0;
    1276             : }
    1277             : 
    1278             : int
    1279           0 : dpdk_link_status_change(VR_INFO_ARGS) {
    1280           0 :     uint16_t port_id = VR_DPDK_INVALID_PORT_ID;
    1281           0 :     int i, idx = -1;
    1282             :     char args[7], oper[4];
    1283             :     char *ptr;
    1284           0 :     unsigned bond_type = VR_DPDK_BOND_MASTER;
    1285             :     struct vr_dpdk_bond_member_info member_info;
    1286           0 :     struct vrouter *router = vrouter_get(0);
    1287             : 
    1288           0 :     VR_INFO_BUF_INIT();
    1289           0 :     memcpy(args, msg_req->inbuf, 7);
    1290             : 
    1291           0 :     ptr = strtok(args, ",");
    1292           0 :     while (ptr != NULL) {
    1293           0 :         if (ptr[0] >= '0' && ptr[0] <= '2')
    1294           0 :             idx = atoi(&ptr[0]);
    1295             :         else
    1296           0 :             memcpy(oper, ptr, 4);
    1297           0 :         ptr = strtok(NULL, ",");
    1298             :     }
    1299             : 
    1300           0 :     if (idx == -1) {
    1301           0 :         VI_PRINTF("Invalid vif ID!\n");
    1302           0 :         return -1;
    1303             :     }
    1304           0 :     for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
    1305           0 :         if (vr_dpdk.ethdevs[i].ethdev_vif_idx == idx) {
    1306           0 :             port_id = vr_dpdk.ethdevs[i].ethdev_port_id;
    1307           0 :             break;
    1308             :         }
    1309             :     }
    1310             : 
    1311           0 :     if (port_id == VR_DPDK_INVALID_PORT_ID) {
    1312           0 :         RTE_LOG(ERR, VROUTER, "Port Id is invalid\n");
    1313           0 :         return -1;
    1314             :     }
    1315             : 
    1316             :     /* Set msginfo */
    1317           0 :     memset(&member_info, 0, sizeof(member_info));
    1318           0 :     strcpy(member_info.intf_name, (char *)router->vr_interfaces[idx]->vif_name);
    1319             : 
    1320           0 :     if(rte_eth_devices[port_id].device->driver->name != NULL)
    1321           0 :         snprintf(member_info.intf_drv_name, (VR_INTERFACE_NAME_LEN - 1),
    1322           0 :                 "%s", rte_eth_devices[port_id].device->driver->name);
    1323             : 
    1324           0 :     if (!strncmp(oper, "up", 2)) {
    1325           0 :         member_info.status = 1;
    1326           0 :     } else if (!strncmp(oper, "down", 4)) {
    1327           0 :         member_info.status = 0;
    1328             :     } else {
    1329           0 :         VI_PRINTF("Enter link operation 'up' or 'down'\n\n");
    1330           0 :         return -1;
    1331             :     }
    1332           0 :     vr_dpdk_nl_send_bond_intf_state(&member_info, bond_type, idx);
    1333             : 
    1334           0 :     return 0;
    1335             : }

Generated by: LCOV version 1.14