diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/debug.cpp | 7 | ||||
-rw-r--r-- | src/internal_api/trex_platform_api.h | 41 | ||||
-rw-r--r-- | src/main_dpdk.cpp | 244 | ||||
-rw-r--r-- | src/main_dpdk.h | 14 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_general.cpp | 86 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmds.h | 8 | ||||
-rw-r--r-- | src/rpc-server/trex_rpc_cmd.cpp | 2 | ||||
-rw-r--r-- | src/rpc-server/trex_rpc_cmds_table.cpp | 2 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless.h | 14 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.cpp | 22 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.h | 9 | ||||
-rw-r--r-- | src/trex_defs.h | 3 | ||||
-rwxr-xr-x | src/trex_port_attr.h | 91 |
13 files changed, 440 insertions, 103 deletions
diff --git a/src/debug.cpp b/src/debug.cpp index 542d2fa1..3a9cd506 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -213,8 +213,11 @@ int CTrexDebug::test_send_pkts(rte_mbuf_t *m, uint16_t queue_id, int num_pkts, i int CTrexDebug::set_promisc_all(bool enable) { int i; for (i=0; i < m_max_ports; i++) { - CPhyEthIF *_if = &m_ports[i]; - _if->set_promiscuous(enable); + if (enable) { + rte_eth_promiscuous_enable(i); + }else{ + rte_eth_promiscuous_disable(i); + } } return 0; diff --git a/src/internal_api/trex_platform_api.h b/src/internal_api/trex_platform_api.h index a55e8cd7..998b6d49 100644 --- a/src/internal_api/trex_platform_api.h +++ b/src/internal_api/trex_platform_api.h @@ -123,7 +123,6 @@ public: */ struct intf_info_st { std::string driver_name; - uint32_t speed; mac_cfg_st mac_info; std::string pci_addr; int numa_node; @@ -149,14 +148,22 @@ public: , uint8_t ipv6_next_h, uint16_t id) const = 0; virtual int del_rx_flow_stat_rule(uint8_t port_id, uint16_t l3_type, uint8_t l4_proto , uint8_t ipv6_next_h, uint16_t id) const = 0; - virtual void set_promiscuous(uint8_t port_id, bool enabled) const = 0; + virtual int set_promiscuous(uint8_t port_id, bool enabled) const = 0; + virtual int set_link_status(uint8_t port_id, bool up) const = 0; virtual bool get_promiscuous(uint8_t port_id) const = 0; + virtual bool get_link_status(uint8_t port_id) const = 0; virtual void flush_dp_messages() const = 0; virtual int get_active_pgids(flow_stat_active_t &result) const = 0; virtual int get_cpu_util_full(cpu_util_full_t &result) const = 0; virtual int get_mbuf_util(Json::Value &result) const = 0; virtual CFlowStatParser *get_flow_stat_parser() const = 0; virtual void mark_for_shutdown() const = 0; + virtual int get_xstats_values(uint8_t port_id, xstats_values_t &xstats_values) const = 0; + virtual int get_xstats_names(uint8_t port_id, xstats_names_t &xstats_names) const = 0; + virtual int get_flow_ctrl(uint8_t port_id, int &mode) const = 0; + virtual int set_flow_ctrl(uint8_t port_id, int mode) const = 0; + virtual int set_led_status(uint8_t port_id, bool on) const = 0; + virtual uint32_t get_link_speed(uint8_t port_id) const = 0; virtual ~TrexPlatformApi() {} }; @@ -188,14 +195,23 @@ public: , uint8_t ipv6_next_h, uint16_t id) const; virtual int del_rx_flow_stat_rule(uint8_t port_id, uint16_t l3_type, uint8_t l4_proto , uint8_t ipv6_next_h, uint16_t id) const; - void set_promiscuous(uint8_t port_id, bool enabled) const; + int set_promiscuous(uint8_t port_id, bool enabled) const; + int set_link_status(uint8_t port_id, bool up) const; bool get_promiscuous(uint8_t port_id) const; + bool get_link_status(uint8_t port_id) const; void flush_dp_messages() const; int get_active_pgids(flow_stat_active_t &result) const; int get_cpu_util_full(cpu_util_full_t &result) const; int get_mbuf_util(Json::Value &result) const; void mark_for_shutdown() const; CFlowStatParser *get_flow_stat_parser() const; + + int get_xstats_values(uint8_t port_id, xstats_values_t &xstats_values) const; + int get_xstats_names(uint8_t port_id, xstats_names_t &xstats_names) const; + int get_flow_ctrl(uint8_t port_id, int &mode) const; + int set_flow_ctrl(uint8_t port_id, int mode) const; + int set_led_status(uint8_t port_id, bool on) const; + uint32_t get_link_speed(uint8_t port_id) const; }; @@ -221,7 +237,6 @@ public: virtual void get_interface_info(uint8_t interface_id, intf_info_st &info) const { info.driver_name = "TEST"; - info.speed = 10000; info.has_crc = true; info.numa_node = 0; @@ -251,11 +266,18 @@ public: , uint8_t ipv6_next_h, uint16_t id) const {return 0;}; virtual int del_rx_flow_stat_rule(uint8_t port_id, uint16_t l3_type, uint8_t l4_proto , uint8_t ipv6_next_h, uint16_t id) const {return 0;}; - void set_promiscuous(uint8_t port_id, bool enabled) const { + int set_promiscuous(uint8_t port_id, bool enabled) const { + return 0; + } + int set_link_status(uint8_t port_id, bool on) const { + return 0; } bool get_promiscuous(uint8_t port_id) const { return false; } + bool get_link_status(uint8_t port_id) const { + return false; + } void flush_dp_messages() const { } @@ -265,6 +287,15 @@ public: CFlowStatParser *get_flow_stat_parser() const {return new CFlowStatParser();} void mark_for_shutdown() const {} + int get_xstats_values(uint8_t port_id, xstats_values_t &xstats_values) const {return 0;}; + int get_xstats_names(uint8_t port_id, xstats_names_t &xstats_names) const {return 0;}; + int get_flow_ctrl(uint8_t port_id, int &mode) const {return 0;}; + int set_flow_ctrl(uint8_t port_id, int mode) const {return 0;}; + int set_led_status(uint8_t port_id, bool on) const {return 0;}; + uint32_t get_link_speed(uint8_t port_id) const { + return 0; + } + private: int m_dp_core_count; diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 46fa7335..9ef08cf1 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -76,7 +76,10 @@ extern "C" { #include "pre_test.h" #include "stateful_rx_core.h" #include "debug.h" +<<<<<<< 653629bee578b4888bd0c144386c03a4b0d08eef #include "pkt_gen.h" +#include "trex_port_attr.h" +>>>>>>> 73cffaf2cc2f21cb902dbd672e93577878c9f6b1 #include "internal_api/trex_platform_api.h" #include "main_dpdk.h" #include "trex_watchdog.h" @@ -120,6 +123,15 @@ static inline int get_is_rx_thread_enabled() { struct port_cfg_t; +#define MAX_DPDK_ARGS 40 +static CPlatformYamlInfo global_platform_cfg_info; +static int global_dpdk_args_num ; +static char * global_dpdk_args[MAX_DPDK_ARGS]; +static char global_cores_str[100]; +static char global_prefix_str[100]; +static char global_loglevel_str[20]; + + class CTRexExtendedDriverBase { public: @@ -158,6 +170,7 @@ public: virtual int verify_fw_ver(int i) {return 0;} virtual CFlowStatParser *get_flow_stat_parser(); virtual int set_rcv_all(CPhyEthIF * _if, bool set_on)=0; + TRexPortAttr * m_port_attr; }; @@ -165,6 +178,7 @@ class CTRexExtendedDriverBase1G : public CTRexExtendedDriverBase { public: CTRexExtendedDriverBase1G(){ + m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), false); } static CTRexExtendedDriverBase * create(){ @@ -210,6 +224,7 @@ public: CTRexExtendedDriverBase1GVm(){ /* we are working in mode that we have 1 queue for rx and one queue for tx*/ CGlobalInfo::m_options.preview.set_vm_one_queue_enable(true); + m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), true); } virtual bool has_crc_added() { @@ -255,6 +270,7 @@ public: class CTRexExtendedDriverBase10G : public CTRexExtendedDriverBase { public: CTRexExtendedDriverBase10G(){ + m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), false); } static CTRexExtendedDriverBase * create(){ @@ -296,6 +312,7 @@ public: // If we want to support more counters in case of card having less interfaces, we // Will have to identify the number of interfaces dynamically. m_if_per_card = 4; + m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), false); } static CTRexExtendedDriverBase * create(){ @@ -345,6 +362,7 @@ private: class CTRexExtendedDriverBaseVIC : public CTRexExtendedDriverBase40G { public: CTRexExtendedDriverBaseVIC(){ + m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), false); } static CTRexExtendedDriverBase * create(){ @@ -413,12 +431,12 @@ private: register_driver(std::string("rte_ixgbe_pmd"),CTRexExtendedDriverBase10G::create); register_driver(std::string("rte_igb_pmd"),CTRexExtendedDriverBase1G::create); register_driver(std::string("rte_i40e_pmd"),CTRexExtendedDriverBase40G::create); + register_driver(std::string("rte_enic_pmd"),CTRexExtendedDriverBaseVIC::create); /* virtual devices */ register_driver(std::string("rte_em_pmd"),CTRexExtendedDriverBase1GVm::create); register_driver(std::string("rte_vmxnet3_pmd"),CTRexExtendedDriverBase1GVm::create); register_driver(std::string("rte_virtio_pmd"),CTRexExtendedDriverBase1GVm::create); - register_driver(std::string("rte_enic_pmd"),CTRexExtendedDriverBaseVIC::create); @@ -488,14 +506,6 @@ static inline int get_min_sample_rate(void){ return ( get_ex_drv()->get_min_sample_rate()); } -#define MAX_DPDK_ARGS 40 -static CPlatformYamlInfo global_platform_cfg_info; -static int global_dpdk_args_num ; -static char * global_dpdk_args[MAX_DPDK_ARGS]; -static char global_cores_str[100]; -static char global_prefix_str[100]; -static char global_loglevel_str[20]; - // cores =0==1,1*2,2,3,4,5,6 // An enum for all the option types enum { OPT_HELP, @@ -1443,63 +1453,158 @@ void CPhyEthIF::disable_flow_control(){ ret, m_port_id); } +// Get user frienly devices description from saved env. var +void TRexPortAttr::update_info(){ + struct rte_pci_addr pci_addr; + char pci[16]; + char * envvar; + std::string pci_envvar_name; + for (uint8_t port_id=0; port_id<total_ports; port_id++) { + pci_addr = rte_eth_devices[port_id].pci_dev->addr; + snprintf(pci, sizeof(pci), "%04x:%02x:%02x.%d", pci_addr.domain, pci_addr.bus, pci_addr.devid, pci_addr.function); + intf_info_st[port_id].pci_addr = pci; + pci_envvar_name = "pci" + intf_info_st[port_id].pci_addr; + std::replace(pci_envvar_name.begin(), pci_envvar_name.end(), ':', '_'); + std::replace(pci_envvar_name.begin(), pci_envvar_name.end(), '.', '_'); + envvar = std::getenv(pci_envvar_name.c_str()); + if (envvar) { + intf_info_st[port_id].description = envvar; + } else { + intf_info_st[port_id].description = "Unknown"; + } + if ( CGlobalInfo::m_options.preview.getVMode() > 0){ + printf("port %d desc: %s\n", port_id, intf_info_st[port_id].description.c_str()); + } + } +} + +int TRexPortAttr::set_led(uint8_t port_id, bool on){ + if (on) { + return rte_eth_led_on(port_id); + }else{ + return rte_eth_led_off(port_id); + } +} + +int TRexPortAttr::get_flow_ctrl(uint8_t port_id, enum rte_eth_fc_mode *mode) { + int ret = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf_tmp); + if (ret) { + return ret; + } + *mode = fc_conf_tmp.mode; + return 0; +} + +int TRexPortAttr::set_flow_ctrl(uint8_t port_id, const enum rte_eth_fc_mode mode) { + int ret = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf_tmp); + if (ret) { + return ret; + } + fc_conf_tmp.mode = mode; + return rte_eth_dev_flow_ctrl_set(port_id, &fc_conf_tmp); +} +void TRexPortAttr::reset_xstats(uint8_t port_id) { + rte_eth_xstats_reset(port_id); +} -void CPhyEthIF::dump_link(FILE *fd){ - fprintf(fd,"port : %d \n",(int)m_port_id); +int TRexPortAttr::get_xstats_values(uint8_t port_id, xstats_values_t &xstats_values) { + int size = rte_eth_xstats_get(port_id, NULL, 0); + if (size < 0) { + return size; + } + xstats_values_tmp.resize(size); + xstats_values.resize(size); + size = rte_eth_xstats_get(port_id, xstats_values_tmp.data(), size); + if (size < 0) { + return size; + } + for (int i=0; i<size; i++) { + xstats_values[xstats_values_tmp[i].id] = xstats_values_tmp[i].value; + } + return 0; +} + +int TRexPortAttr::get_xstats_names(uint8_t port_id, xstats_names_t &xstats_names){ + int size = rte_eth_xstats_get_names(port_id, NULL, 0); + if (size < 0) { + return size; + } + xstats_names_tmp.resize(size); + xstats_names.resize(size); + size = rte_eth_xstats_get_names(port_id, xstats_names_tmp.data(), size); + if (size < 0) { + return size; + } + for (int i=0; i<size; i++) { + xstats_names[i] = xstats_names_tmp[i].name; + } + return 0; +} + +void TRexPortAttr::dump_link(uint8_t port_id, FILE *fd){ + fprintf(fd,"port : %d \n",(int)port_id); fprintf(fd,"------------\n"); fprintf(fd,"link : "); - if (m_link.link_status) { + if (m_link[port_id].link_status) { fprintf(fd," link : Link Up - speed %u Mbps - %s\n", - (unsigned) m_link.link_speed, - (m_link.link_duplex == ETH_LINK_FULL_DUPLEX) ? + (unsigned) m_link[port_id].link_speed, + (m_link[port_id].link_duplex == ETH_LINK_FULL_DUPLEX) ? ("full-duplex") : ("half-duplex\n")); } else { fprintf(fd," Link Down\n"); } - fprintf(fd,"promiscuous : %d \n",get_promiscuous()); + fprintf(fd,"promiscuous : %d \n",get_promiscuous(port_id)); } -void CPhyEthIF::update_link_status(){ - rte_eth_link_get(m_port_id, &m_link); +void TRexPortAttr::update_link_status(uint8_t port_id){ + rte_eth_link_get(port_id, &m_link[port_id]); } -void CPhyEthIF::update_link_status_nowait(){ - rte_eth_link_get_nowait(m_port_id, &m_link); +void TRexPortAttr::update_link_status_nowait(uint8_t port_id){ + rte_eth_link_get_nowait(port_id, &m_link[port_id]); } -void CPhyEthIF::add_mac(char * mac){ +int TRexPortAttr::add_mac(uint8_t port_id, char * mac){ struct ether_addr mac_addr; - int i=0; - for (i=0; i<6;i++) { + for (int i=0; i<6;i++) { mac_addr.addr_bytes[i] =mac[i]; } - rte_eth_dev_mac_addr_add(m_port_id, &mac_addr,0); + return rte_eth_dev_mac_addr_add(port_id, &mac_addr,0); } -void CPhyEthIF::set_promiscuous(bool enable){ +int TRexPortAttr::set_promiscuous(uint8_t port_id, bool enable){ if (enable) { - rte_eth_promiscuous_enable(m_port_id); + rte_eth_promiscuous_enable(port_id); + }else{ + rte_eth_promiscuous_disable(port_id); + } + return 0; +} + +int TRexPortAttr::set_link_up(uint8_t port_id, bool up){ + if (up) { + return rte_eth_dev_set_link_up(port_id); }else{ - rte_eth_promiscuous_disable(m_port_id); + return rte_eth_dev_set_link_down(port_id); } } -bool CPhyEthIF::get_promiscuous(){ - int ret=rte_eth_promiscuous_get(m_port_id); +bool TRexPortAttr::get_promiscuous(uint8_t port_id){ + int ret=rte_eth_promiscuous_get(port_id); if (ret<0) { rte_exit(EXIT_FAILURE, "rte_eth_promiscuous_get: " "err=%d, port=%u\n", - ret, m_port_id); + ret, port_id); } return ( ret?true:false); } -void CPhyEthIF::macaddr_get(struct ether_addr *mac_addr){ - rte_eth_macaddr_get(m_port_id , mac_addr); +void TRexPortAttr::macaddr_get(uint8_t port_id, struct ether_addr *mac_addr){ + rte_eth_macaddr_get(port_id , mac_addr); } int CPhyEthIF::dump_fdir_global_stats(FILE *fd) { @@ -1929,12 +2034,22 @@ int CCoreEthIF::send_pkt_lat(CCorePerPort *lp_port, rte_mbuf_t *m, CVirtualIFPer int ret = lp_port->m_port->tx_burst(lp_port->m_tx_queue_id_lat, &m, 1); +#ifdef DELAY_IF_NEEDED while ( unlikely( ret != 1 ) ){ rte_delay_us(1); lp_stats->m_tx_queue_full += 1; ret = lp_port->m_port->tx_burst(lp_port->m_tx_queue_id_lat, &m, 1); } +#else + if ( unlikely( ret != 1 ) ) { + lp_stats->m_tx_drop ++; + rte_pktmbuf_free(m); + return 0; + } + +#endif + return ret; } @@ -2867,6 +2982,8 @@ public: CLatencyManager m_mg; // statefull RX core CRxCoreStateless m_rx_sl; // stateless RX core CTrexGlobalIoMode m_io_modes; + CTRexExtendedDriverBase * m_drv; + TRexPortAttr * m_port_attr; private: CLatencyHWPort m_latency_vports[TREX_MAX_PORTS]; /* read hardware driver */ @@ -3000,11 +3117,11 @@ bool CGlobalTRex::is_all_links_are_up(bool dump){ int i; for (i=0; i<m_max_ports; i++) { CPhyEthIF * _if=&m_ports[i]; - _if->update_link_status(); + m_port_attr->update_link_status(i); if ( dump ){ _if->dump_stats(stdout); } - if ( _if->is_link_up() == false){ + if ( m_port_attr->is_link_up(i) == false){ all_link_are=false; break; } @@ -3238,7 +3355,7 @@ int CGlobalTRex::ixgbe_start(void){ _if->disable_flow_control(); } - _if->add_mac((char *)CGlobalInfo::m_options.get_src_mac_addr(i)); + m_port_attr->add_mac(i, (char *)CGlobalInfo::m_options.get_src_mac_addr(i)); fflush(stdout); } @@ -3247,7 +3364,7 @@ int CGlobalTRex::ixgbe_start(void){ /* wait for ports to be stable */ get_ex_drv()->wait_for_stable_link(); - if ( !is_all_links_are_up(true) ){ + if ( !is_all_links_are_up(true) && !get_is_stateless()){ dump_links_status(stdout); rte_exit(EXIT_FAILURE, " " " one of the link is down \n"); @@ -3478,10 +3595,13 @@ int CGlobalTRex::ixgbe_prob_init(void){ } CTRexExtendedDriverDb::Ins()->set_driver_name(dev_info.driver_name); + m_drv = CTRexExtendedDriverDb::Ins()->get_drv(); + m_port_attr = m_drv->m_port_attr; + m_port_attr->update_info(); // check if firmware version is new enough for (i = 0; i < m_max_ports; i++) { - if (CTRexExtendedDriverDb::Ins()->get_drv()->verify_fw_ver(i) < 0) { + if (m_drv->verify_fw_ver(i) < 0) { // error message printed by verify_fw_ver exit(1); } @@ -3552,9 +3672,8 @@ void CGlobalTRex::dump_config(FILE *fd){ void CGlobalTRex::dump_links_status(FILE *fd){ for (int i=0; i<m_max_ports; i++) { - CPhyEthIF * _if=&m_ports[i]; - _if->update_link_status_nowait(); - _if->dump_link(fd); + m_port_attr->update_link_status_nowait(i); + m_port_attr->dump_link(i, fd); } } @@ -4006,6 +4125,10 @@ void CGlobalTRex::handle_slow_path() { m_stats_cnt+=1; + // update speed, link up/down etc. + for (int i=0; i<m_max_ports; i++) { + m_port_attr->update_link_status_nowait(i); + } if ( CGlobalInfo::m_options.preview.get_no_keyboard() ==false ) { if ( m_io_modes.handle_io_modes() ) { @@ -6203,6 +6326,21 @@ static void trex_termination_handler(int signum) { * TODO: REMOVE THIS TO A SEPERATE FILE * **********************************************************/ +int TrexDpdkPlatformApi::get_xstats_values(uint8_t port_id, xstats_values_t &xstats_values) const { + return g_trex.m_port_attr->get_xstats_values(port_id, xstats_values); +} + +int TrexDpdkPlatformApi::get_xstats_names(uint8_t port_id, xstats_names_t &xstats_names) const { + return g_trex.m_port_attr->get_xstats_names(port_id, xstats_names); +} + +int TrexDpdkPlatformApi::get_flow_ctrl(uint8_t port_id, int &mode) const{ + return g_trex.m_port_attr->get_flow_ctrl(port_id, (enum rte_eth_fc_mode *) &mode); +} +int TrexDpdkPlatformApi::set_flow_ctrl(uint8_t port_id, int mode) const { + return g_trex.m_port_attr->set_flow_ctrl(port_id, (enum rte_eth_fc_mode) mode); +} + void TrexDpdkPlatformApi::get_port_num(uint8_t &port_num) const { port_num = g_trex.m_max_ports; } @@ -6248,19 +6386,22 @@ TrexDpdkPlatformApi::port_id_to_cores(uint8_t port_id, std::vector<std::pair<uin cores_id_list = lpt->get_core_list(); } +uint32_t +TrexDpdkPlatformApi::get_link_speed(uint8_t port_id) const { + return g_trex.m_port_attr->get_link_speed(port_id); +} + void TrexDpdkPlatformApi::get_interface_info(uint8_t interface_id, intf_info_st &info) const { struct ether_addr rte_mac_addr; info.driver_name = CTRexExtendedDriverDb::Ins()->get_driver_name(); - g_trex.m_ports[interface_id].update_link_status_nowait(); - g_trex.m_ports[interface_id].get_link_speed(&info.speed); info.has_crc = CTRexExtendedDriverDb::Ins()->get_drv()->has_crc_added(); /* mac INFO */ /* hardware */ - g_trex.m_ports[interface_id].macaddr_get(&rte_mac_addr); + g_trex.m_port_attr->macaddr_get(interface_id, &rte_mac_addr); assert(ETHER_ADDR_LEN == 6); /* software */ @@ -6329,12 +6470,25 @@ int TrexDpdkPlatformApi::del_rx_flow_stat_rule(uint8_t port_id, uint16_t l3_type ->add_del_rx_flow_stat_rule(port_id, RTE_ETH_FILTER_DELETE, l3_type, l4_proto, ipv6_next_h, id); } -void TrexDpdkPlatformApi::set_promiscuous(uint8_t port_id, bool enabled) const { - g_trex.m_ports[port_id].set_promiscuous(enabled); +int TrexDpdkPlatformApi::set_promiscuous(uint8_t port_id, bool enabled) const { + g_trex.m_port_attr->set_promiscuous(port_id, enabled); + return 0; } bool TrexDpdkPlatformApi::get_promiscuous(uint8_t port_id) const { - return g_trex.m_ports[port_id].get_promiscuous(); + return g_trex.m_port_attr->get_promiscuous(port_id); +} + +int TrexDpdkPlatformApi::set_link_status(uint8_t port_id, bool up) const { + return g_trex.m_port_attr->set_link_up(port_id, up); +} + +bool TrexDpdkPlatformApi::get_link_status(uint8_t port_id) const { + return g_trex.m_port_attr->is_link_up(port_id); +} + +int TrexDpdkPlatformApi::set_led_status(uint8_t port_id, bool on) const { + return g_trex.m_port_attr->set_led(port_id, on); } void TrexDpdkPlatformApi::flush_dp_messages() const { diff --git a/src/main_dpdk.h b/src/main_dpdk.h index 97994c47..640c73e4 100644 --- a/src/main_dpdk.h +++ b/src/main_dpdk.h @@ -87,7 +87,6 @@ class CPhyEthIF { void configure(uint16_t nb_rx_queue, uint16_t nb_tx_queue, const struct rte_eth_conf *eth_conf); - void macaddr_get(struct ether_addr *mac_addr); void get_stats(CPhyEthIFStats *stats); int dump_fdir_global_stats(FILE *fd); int reset_hw_flow_stats(); @@ -106,19 +105,7 @@ class CPhyEthIF { void configure_rx_duplicate_rules(); void start(); void stop(); - void update_link_status(); - void update_link_status_nowait(); - bool is_link_up(){ - return (m_link.link_status?true:false); - } - void get_link_speed(uint32_t *link_speed){ - *link_speed = m_link.link_speed; - } - void dump_link(FILE *fd); void disable_flow_control(); - void set_promiscuous(bool enable); - void add_mac(char * mac); - bool get_promiscuous(); void dump_stats(FILE *fd); void set_ignore_stats_base(CPreTestStats &pre_stats); void update_counters(); @@ -182,7 +169,6 @@ class CPhyEthIF { const std::vector<std::pair<uint8_t, uint8_t>> & get_core_list(); private: - struct rte_eth_link m_link; uint8_t m_port_id; uint8_t m_rx_queue; uint64_t m_sw_try_tx_pkt; diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp index 342ec594..f6b088a5 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp @@ -346,18 +346,38 @@ trex_rpc_cmd_rc_e TrexRpcCmdSetPortAttr::_run(const Json::Value ¶ms, Json::Value &result) { uint8_t port_id = parse_port(params, result); - TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); const Json::Value &attr = parse_object(params, "attr", result); - + int ret = 0; /* iterate over all attributes in the dict */ for (const std::string &name : attr.getMemberNames()) { - - /* handle promiscuous */ if (name == "promiscuous") { bool enabled = parse_bool(attr[name], "enabled", result); - port->set_promiscuous(enabled); + ret = get_stateless_obj()->get_platform_api()->set_promiscuous(port_id, enabled); + } + else if (name == "link_status") { + bool up = parse_bool(attr[name], "up", result); + ret = get_stateless_obj()->get_platform_api()->set_link_status(port_id, up); + } + else if (name == "led_status") { + bool on = parse_bool(attr[name], "on", result); + ret = get_stateless_obj()->get_platform_api()->set_led_status(port_id, on); + } else if (name == "flow_ctrl_mode") { + int mode = parse_int(attr[name], "mode", result); + ret = get_stateless_obj()->get_platform_api()->set_flow_ctrl(port_id, mode); + } else { + generate_execute_err(result, "Not recognized attribute: " + name); + break; } + if (ret != 0){ + if ( ret == -ENOTSUP ) { + generate_execute_err(result, "Error applying " + name + ": operation is not supported for this NIC."); + } + else if (ret) { + generate_execute_err(result, "Error applying " + name + " attribute, return value: " + to_string(ret)); + } + } + break; } result["result"] = Json::objectValue; @@ -437,6 +457,60 @@ TrexRpcCmdRelease::_run(const Json::Value ¶ms, Json::Value &result) { } /** + * get port extended stats names (keys of dict) + * + */ +trex_rpc_cmd_rc_e +TrexRpcCmdGetPortXStatsNames::_run(const Json::Value ¶ms, Json::Value &result) { + + uint8_t port_id = parse_port(params, result); + xstats_names_t xstats_names; + + int ret = get_stateless_obj()->get_platform_api()->get_xstats_names(port_id, xstats_names); + if (ret < 0) { + if ( ret == -ENOTSUP ) { + generate_execute_err(result, "Operation not supported"); + } + else if (ret) { + generate_execute_err(result, "Operation failed, error code: " + to_string(ret)); + } + } else { + for (int i=0; i<xstats_names.size(); i++) { + result["result"]["xstats_names"].append(xstats_names[i]); + } + } + + return (TREX_RPC_CMD_OK); +} + +/** + * get port extended stats (values of dict) + * + */ +trex_rpc_cmd_rc_e +TrexRpcCmdGetPortXStatsValues::_run(const Json::Value ¶ms, Json::Value &result) { + + uint8_t port_id = parse_port(params, result); + xstats_values_t xstats_values; + + int ret = get_stateless_obj()->get_platform_api()->get_xstats_values(port_id, xstats_values); + if (ret < 0) { + if ( ret == -ENOTSUP ) { + generate_execute_err(result, "Operation not supported"); + } + else if (ret) { + generate_execute_err(result, "Operation failed, error code: " + to_string(ret)); + } + } else { + for (int i=0; i<xstats_values.size(); i++) { + result["result"]["xstats_values"].append((Json::Value::UInt64) xstats_values[i]); + } + } + + return (TREX_RPC_CMD_OK); +} + +/** * get port stats * */ @@ -477,7 +551,7 @@ TrexRpcCmdGetPortStatus::_run(const Json::Value ¶ms, Json::Value &result) { result["result"]["max_stream_id"] = port->get_max_stream_id(); /* attributes */ - result["result"]["attr"]["promiscuous"]["enabled"] = port->get_promiscuous(); + result["result"]["attr"]["promiscuous"]["enabled"] = get_stateless_obj()->get_platform_api()->get_promiscuous(port_id); return (TREX_RPC_CMD_OK); } diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h index a68796ae..5fde1d0c 100644 --- a/src/rpc-server/commands/trex_rpc_cmds.h +++ b/src/rpc-server/commands/trex_rpc_cmds.h @@ -87,9 +87,11 @@ TREX_RPC_CMD_DEFINE(TrexRpcCmdRelease, "release", 1, true, APIClass: /** * port commands */ -TREX_RPC_CMD_DEFINE(TrexRpcCmdGetPortStats, "get_port_stats", 1, false, APIClass::API_CLASS_TYPE_CORE); -TREX_RPC_CMD_DEFINE(TrexRpcCmdGetPortStatus, "get_port_status", 1, false, APIClass::API_CLASS_TYPE_CORE); -TREX_RPC_CMD_DEFINE(TrexRpcCmdSetPortAttr, "set_port_attr", 3, false, APIClass::API_CLASS_TYPE_CORE); +TREX_RPC_CMD_DEFINE(TrexRpcCmdGetPortStats, "get_port_stats", 1, false, APIClass::API_CLASS_TYPE_CORE); +TREX_RPC_CMD_DEFINE(TrexRpcCmdGetPortStatus, "get_port_status", 1, false, APIClass::API_CLASS_TYPE_CORE); +TREX_RPC_CMD_DEFINE(TrexRpcCmdSetPortAttr, "set_port_attr", 2, true, APIClass::API_CLASS_TYPE_CORE); +TREX_RPC_CMD_DEFINE(TrexRpcCmdGetPortXStatsValues, "get_port_xstats_values", 1, false, APIClass::API_CLASS_TYPE_CORE); +TREX_RPC_CMD_DEFINE(TrexRpcCmdGetPortXStatsNames, "get_port_xstats_names", 1, false, APIClass::API_CLASS_TYPE_CORE); /** * stream cmds diff --git a/src/rpc-server/trex_rpc_cmd.cpp b/src/rpc-server/trex_rpc_cmd.cpp index 28145f13..265d426b 100644 --- a/src/rpc-server/trex_rpc_cmd.cpp +++ b/src/rpc-server/trex_rpc_cmd.cpp @@ -87,7 +87,7 @@ TrexRpcCommand::check_param_count(const Json::Value ¶ms, int expected, Json: if (params.size() < expected) { std::stringstream ss; - ss << "method expects at least '" << expected << "' parameter(s), '" << params.size() << "' provided"; + ss << "method '" << m_name << "' expects at least " << expected << " parameter(s), " << params.size() << " provided"; generate_parse_err(result, ss.str()); } } diff --git a/src/rpc-server/trex_rpc_cmds_table.cpp b/src/rpc-server/trex_rpc_cmds_table.cpp index 762dd614..cddf19b9 100644 --- a/src/rpc-server/trex_rpc_cmds_table.cpp +++ b/src/rpc-server/trex_rpc_cmds_table.cpp @@ -47,6 +47,8 @@ TrexRpcCommandsTable::TrexRpcCommandsTable() { register_command(new TrexRpcCmdGetPortStats()); register_command(new TrexRpcCmdGetPortStatus()); register_command(new TrexRpcCmdSetPortAttr()); + register_command(new TrexRpcCmdGetPortXStatsValues()); + register_command(new TrexRpcCmdGetPortXStatsNames()); /* stream commands */ diff --git a/src/stateless/cp/trex_stateless.h b/src/stateless/cp/trex_stateless.h index 7ea669df..070cd6de 100644 --- a/src/stateless/cp/trex_stateless.h +++ b/src/stateless/cp/trex_stateless.h @@ -91,7 +91,7 @@ public: } const TrexRpcServerConfig *m_rpc_req_resp_cfg; - const TrexPlatformApi *m_platform_api; + TrexPlatformApi *m_platform_api; bool m_rpc_server_verbose; uint8_t m_port_count; TrexPublisher *m_publisher; @@ -137,6 +137,18 @@ public: void shutdown(); /** + * fetch xstats names (keys of dict) + * + */ + void encode_xstats_names(Json::Value &global); + + /** + * fetch xstats values + * + */ + void encode_xstats_values(Json::Value &global); + + /** * fetch all the stats * */ diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 58410fea..8c6a1573 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -153,7 +153,7 @@ private: * trex stateless port * **************************/ -TrexStatelessPort::TrexStatelessPort(uint8_t port_id, const TrexPlatformApi *api) : m_dp_events(this) { +TrexStatelessPort::TrexStatelessPort(uint8_t port_id, const TrexPlatformApi *api) : platform_api(api), m_dp_events(this) { std::vector<std::pair<uint8_t, uint8_t>> core_pair_list; m_port_id = port_id; @@ -581,7 +581,7 @@ void TrexStatelessPort::get_properties(std::string &driver, uint32_t &speed) { driver = m_api_info.driver_name; - speed = m_api_info.speed; + speed = platform_api->get_link_speed(m_port_id); } bool @@ -609,10 +609,8 @@ TrexStatelessPort::change_state(port_state_e new_state) { void TrexStatelessPort::encode_stats(Json::Value &port) { - const TrexPlatformApi *api = get_stateless_obj()->get_platform_api(); - TrexPlatformInterfaceStats stats; - api->get_interface_stats(m_port_id, stats); + platform_api->get_interface_stats(m_port_id, stats); port["tx_bps"] = stats.m_stats.m_tx_bps; port["rx_bps"] = stats.m_stats.m_rx_bps; @@ -664,7 +662,7 @@ TrexStatelessPort::send_message_to_rx(TrexStatelessCpToRxMsgBase *msg) { uint64_t TrexStatelessPort::get_port_speed_bps() const { - return (uint64_t) m_api_info.speed * 1000 * 1000; + return (uint64_t) platform_api->get_link_speed(m_port_id) * 1000 * 1000; } static inline double @@ -869,18 +867,6 @@ TrexStatelessPort::get_port_effective_rate(double &pps, } - -void -TrexStatelessPort::set_promiscuous(bool enabled) { - get_stateless_obj()->get_platform_api()->set_promiscuous(m_port_id, enabled); -} - -bool -TrexStatelessPort::get_promiscuous() { - return get_stateless_obj()->get_platform_api()->get_promiscuous(m_port_id); -} - - void TrexStatelessPort::get_macaddr(std::string &hw_macaddr, std::string &src_macaddr, diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h index 147efc70..00139973 100644 --- a/src/stateless/cp/trex_stateless_port.h +++ b/src/stateless/cp/trex_stateless_port.h @@ -363,14 +363,6 @@ public: double &percentage); - /** - * set port promiscuous on/off - * - * @param enabled - */ - void set_promiscuous(bool enabled); - bool get_promiscuous(); - void get_macaddr(std::string &hw_macaddr, std::string &src_macaddr, std::string &dst_macaddr); @@ -443,6 +435,7 @@ private: port_state_e m_port_state; TrexPlatformApi::intf_info_st m_api_info; + const TrexPlatformApi *platform_api; uint16_t m_rx_count_num; uint16_t m_rx_caps; diff --git a/src/trex_defs.h b/src/trex_defs.h index c659c337..d8139a83 100644 --- a/src/trex_defs.h +++ b/src/trex_defs.h @@ -16,6 +16,7 @@ limitations under the License. #include <set> #include <queue> #include <vector> +#include <string> #ifndef __TREX_DEFS_H__ #define __TREX_DEFS_H__ @@ -52,5 +53,7 @@ struct cpu_vct_st { typedef std::set<uint32_t> flow_stat_active_t; typedef std::set<uint32_t>::iterator flow_stat_active_it_t; typedef std::vector<cpu_vct_st> cpu_util_full_t; +typedef std::vector<std::string> xstats_names_t; +typedef std::vector<uint64_t> xstats_values_t; #endif diff --git a/src/trex_port_attr.h b/src/trex_port_attr.h new file mode 100755 index 00000000..037a3de3 --- /dev/null +++ b/src/trex_port_attr.h @@ -0,0 +1,91 @@ +/* +Copyright (c) 2015-2015 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef __TREX_PORT_ATTR_H__ +#define __TREX_PORT_ATTR_H__ + +#include <string> +#include <vector> +#include <rte_ethdev.h> +#include "trex_defs.h" + + +class TRexPortAttr { +public: + TRexPortAttr(uint8_t total_ports, bool is_virtual = false) : total_ports(total_ports) { + flag_is_virtual = is_virtual; + m_link.resize(total_ports); + intf_info_st.resize(total_ports); + } + +/* UPDATES */ + virtual void update_link_status(uint8_t port_id); + virtual void update_link_status_nowait(uint8_t port_id); + virtual void reset_xstats(uint8_t port_id); + virtual void update_info(); + +/* GETTERS */ + virtual bool get_promiscuous(uint8_t port_id); + virtual void macaddr_get(uint8_t port_id, struct ether_addr *mac_addr); + virtual uint32_t get_link_speed(uint8_t port_id) { return m_link[port_id].link_speed; } // L1 Mbps + virtual bool is_link_duplex(uint8_t port_id) { return (m_link[port_id].link_duplex ? true : false); } + virtual bool is_link_autoneg(uint8_t port_id) { return (m_link[port_id].link_autoneg ? true : false); } + virtual bool is_link_up(uint8_t port_id) { return (m_link[port_id].link_status ? true : false); } + virtual int get_xstats_values(uint8_t port_id, xstats_values_t &xstats_values); + virtual int get_xstats_names(uint8_t port_id, xstats_names_t &xstats_names); + virtual int get_flow_ctrl(uint8_t port_id, enum rte_eth_fc_mode *mode); + +/* SETTERS */ + virtual int set_promiscuous(uint8_t port_id, bool enabled); + virtual int add_mac(uint8_t port_id, char * mac); + virtual int set_link_up(uint8_t port_id, bool up); + virtual int set_flow_ctrl(uint8_t port_id, const enum rte_eth_fc_mode mode); + virtual int set_led(uint8_t port_id, bool on); + + +/* DUMPS */ + virtual void dump_link(uint8_t port_id, FILE *fd); + virtual bool is_virtual() { + return flag_is_virtual; + } + +private: + bool flag_is_virtual; + const uint8_t total_ports; + rte_eth_fc_conf fc_conf_tmp; + std::vector <rte_eth_link> m_link; + std::vector<struct rte_eth_xstat> xstats_values_tmp; + std::vector<struct rte_eth_xstat_name> xstats_names_tmp; + + struct mac_cfg_st { + uint8_t hw_macaddr[6]; + uint8_t src_macaddr[6]; + uint8_t dst_macaddr[6]; + }; + + struct intf_info_st_type { + mac_cfg_st mac_info; + std::string pci_addr; + std::string description; + int numa_node; + }; + + std::vector <intf_info_st_type> intf_info_st; + +}; + + +#endif /* __TREX_PORT_ATTR_H__ */ |