diff options
author | 2016-10-22 10:38:27 +0200 | |
---|---|---|
committer | 2016-10-28 14:38:32 +0200 | |
commit | 2dab6b6d09f9f1474d2ade6b465ebfa5ce3b3f5e (patch) | |
tree | bab2898d6b631d5495c62a8ad4b86ccea4eae786 /src | |
parent | 00bfc58e6f76f7a67a6b62f297f72792534fef52 (diff) |
dpdk_setup_ports.py: fix add of help in case of "t-rex-64 --help"
dpdk_setup_ports.py: fix warning of TRex is already running if different NICs are being used
singleton_daemon.py: fix error socket in use immediately after check if in use
trex-console: fix crash in case of "tui --help"
trex-console: try-catch commands instead of crashing
add async notification on port status/atttibutes change
add port xstats support
add description of interfaces
main_dpdk.cpp: fix --client_cfg not working with Python API
Signed-off-by: Yaroslav Brustinov <ybrustin@cisco.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/dpdk/drivers/net/virtio/virtio_ethdev.c | 2 | ||||
-rw-r--r-- | src/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.c | 2 | ||||
-rw-r--r-- | src/internal_api/trex_platform_api.h | 45 | ||||
-rw-r--r-- | src/main_dpdk.cpp | 138 | ||||
-rw-r--r-- | src/pal/linux/rte_ethdev_includes.h | 23 | ||||
-rw-r--r-- | src/pal/linux_dpdk/rte_ethdev_includes.h | 1 | ||||
-rw-r--r-- | src/publisher/trex_publisher.h | 1 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_general.cpp | 39 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.cpp | 11 | ||||
-rw-r--r-- | src/stateless/cp/trex_streams_compiler.h | 6 | ||||
-rw-r--r-- | src/trex_defs.h | 1 | ||||
-rwxr-xr-x | src/trex_port_attr.h | 39 |
12 files changed, 198 insertions, 110 deletions
diff --git a/src/dpdk/drivers/net/virtio/virtio_ethdev.c b/src/dpdk/drivers/net/virtio/virtio_ethdev.c index 07d64497..35e67b90 100644 --- a/src/dpdk/drivers/net/virtio/virtio_ethdev.c +++ b/src/dpdk/drivers/net/virtio/virtio_ethdev.c @@ -1550,6 +1550,8 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->default_txconf = (struct rte_eth_txconf) { .txq_flags = ETH_TXQ_FLAGS_NOOFFLOADS }; + /* TRex patch */ + dev_info->speed_capa = ETH_LINK_SPEED_10G; } /* diff --git a/src/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.c b/src/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.c index 58742153..47fdc3ec 100644 --- a/src/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.c +++ b/src/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.c @@ -706,6 +706,8 @@ vmxnet3_dev_info_get(__attribute__((unused))struct rte_eth_dev *dev, dev_info->min_rx_bufsize = 1518 + RTE_PKTMBUF_HEADROOM; dev_info->max_rx_pktlen = 16384; /* includes CRC, cf MAXFRS register */ dev_info->max_mac_addrs = VMXNET3_MAX_MAC_ADDRS; + /* TRex patch */ + dev_info->speed_capa = ETH_LINK_SPEED_10G; dev_info->default_txconf.txq_flags = ETH_TXQ_FLAGS_NOXSUMSCTP; dev_info->flow_type_rss_offloads = VMXNET3_RSS_OFFLOAD_ALL; diff --git a/src/internal_api/trex_platform_api.h b/src/internal_api/trex_platform_api.h index 998b6d49..0141186e 100644 --- a/src/internal_api/trex_platform_api.h +++ b/src/internal_api/trex_platform_api.h @@ -28,6 +28,7 @@ limitations under the License. #include <string.h> #include "flow_stat_parser.h" #include "trex_defs.h" +#include "trex_port_attr.h" #include <json/json.h> /** @@ -136,6 +137,7 @@ public: virtual void get_interface_info(uint8_t interface_id, intf_info_st &info) const = 0; virtual void publish_async_data_now(uint32_t key, bool baseline) const = 0; + virtual void publish_async_port_attr_changed(uint8_t port_id) const = 0; virtual uint8_t get_dp_core_count() const = 0; virtual void get_interface_stat_info(uint8_t interface_id, uint16_t &num_counters, uint16_t &capabilities) const =0; virtual int get_flow_stats(uint8_t port_id, void *stats, void *tx_stats, int min, int max, bool reset @@ -148,22 +150,15 @@ 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 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 TRexPortAttr *getPortAttrObj() 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() {} }; @@ -183,6 +178,7 @@ public: void get_interface_info(uint8_t interface_id, intf_info_st &info) const; void publish_async_data_now(uint32_t key, bool baseline) const; + void publish_async_port_attr_changed(uint8_t port_id) const; uint8_t get_dp_core_count() const; void get_interface_stat_info(uint8_t interface_id, uint16_t &num_counters, uint16_t &capabilities) const; int get_flow_stats(uint8_t port_id, void *stats, void *tx_stats, int min, int max, bool reset @@ -195,23 +191,16 @@ 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; - 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; + TRexPortAttr *getPortAttrObj() 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; }; @@ -256,6 +245,10 @@ public: virtual void publish_async_data_now(uint32_t key, bool baseline) const { } + + virtual void publish_async_port_attr_changed(uint8_t port_id) const { + } + int get_flow_stats(uint8_t port_id, void *stats, void *tx_stats, int min, int max, bool reset , TrexPlatformApi::driver_stat_cap_e type) const {return 0;}; virtual int get_rfc2544_info(void *rfc2544_info, int min, int max, bool reset) const {return 0;}; @@ -266,18 +259,6 @@ 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;}; - 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 { } @@ -285,17 +266,11 @@ public: int get_cpu_util_full(cpu_util_full_t &result) const {return 0;} int get_mbuf_util(Json::Value &result) const {return 0;} CFlowStatParser *get_flow_stat_parser() const {return new CFlowStatParser();} + TRexPortAttr *getPortAttrObj() const {printf("Port attributes should not be used in simulation\n"); return NULL;} // dummy 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 9ef08cf1..cd4c782b 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -159,7 +159,7 @@ public: virtual void clear_extended_stats(CPhyEthIF * _if)=0; virtual int wait_for_stable_link(); virtual void wait_after_link_up(); - virtual bool flow_control_disable_supported(){return true;} + virtual bool flow_control_disable_supported(){return m_port_attr->is_fc_change_supported();} virtual bool hw_rx_stat_supported(){return false;} virtual int get_rx_stats(CPhyEthIF * _if, uint32_t *pkts, uint32_t *prev_pkts, uint32_t *bytes, uint32_t *prev_bytes , int min, int max) {return -1;} @@ -178,7 +178,7 @@ class CTRexExtendedDriverBase1G : public CTRexExtendedDriverBase { public: CTRexExtendedDriverBase1G(){ - m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), false); + m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), false, true); } static CTRexExtendedDriverBase * create(){ @@ -224,7 +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); + m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), true, true); } virtual bool has_crc_added() { @@ -270,7 +270,7 @@ public: class CTRexExtendedDriverBase10G : public CTRexExtendedDriverBase { public: CTRexExtendedDriverBase10G(){ - m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), false); + m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), false, true); } static CTRexExtendedDriverBase * create(){ @@ -312,7 +312,8 @@ 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); + // disabling flow control on 40G using DPDK API causes the interface to malfunction + m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), false, false); } static CTRexExtendedDriverBase * create(){ @@ -342,8 +343,6 @@ public: return TrexPlatformApi::IF_STAT_IPV4_ID | TrexPlatformApi::IF_STAT_PAYLOAD; } virtual int wait_for_stable_link(); - // disabling flow control on 40G using DPDK API causes the interface to malfunction - virtual bool flow_control_disable_supported(){return false;} virtual bool hw_rx_stat_supported(){return true;} virtual int verify_fw_ver(int i); virtual CFlowStatParser *get_flow_stat_parser(); @@ -362,7 +361,7 @@ private: class CTRexExtendedDriverBaseVIC : public CTRexExtendedDriverBase40G { public: CTRexExtendedDriverBaseVIC(){ - m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), false); + m_port_attr = new TRexPortAttr(global_platform_cfg_info.m_if_list.size(), false, false); } static CTRexExtendedDriverBase * create(){ @@ -375,8 +374,6 @@ public: virtual int verify_fw_ver(int i) {return 0;} - bool flow_control_disable_supported(){return false;} - virtual void update_configuration(port_cfg_t * cfg); }; @@ -599,6 +596,7 @@ static CSimpleOpt::SOption parser_options[] = { OPT_NO_FLOW_CONTROL, "--no-flow-control-change", SO_NONE }, { OPT_VLAN, "--vlan", SO_NONE }, { OPT_CLIENT_CFG_FILE, "--client_cfg", SO_REQ_SEP }, + { OPT_CLIENT_CFG_FILE, "--client-cfg", SO_REQ_SEP }, { OPT_NO_KEYBOARD_INPUT ,"--no-key", SO_NONE }, { OPT_VIRT_ONE_TX_RX_QUEUE, "--vm-sim", SO_NONE }, { OPT_PREFIX, "--prefix", SO_REQ_SEP }, @@ -1453,8 +1451,11 @@ void CPhyEthIF::disable_flow_control(){ ret, m_port_id); } -// Get user frienly devices description from saved env. var -void TRexPortAttr::update_info(){ +/* +Get user frienly devices description from saved env. var +Changes certain attributes based on description +*/ +void TRexPortAttr::update_descriptions(){ struct rte_pci_addr pci_addr; char pci[16]; char * envvar; @@ -1472,6 +1473,13 @@ void TRexPortAttr::update_info(){ } else { intf_info_st[port_id].description = "Unknown"; } + if (intf_info_st[port_id].description.find("82599ES") != std::string::npos) { // works for 82599EB etc. DPDK does not distinguish them + flag_is_link_change_supported = false; + } + if (intf_info_st[port_id].description.find("82545EM") != std::string::npos) { // in virtual E1000, DPDK claims fc is supported, but it's not + flag_is_fc_change_supported = false; + flag_is_led_change_supported = false; + } if ( CGlobalInfo::m_options.preview.getVMode() > 0){ printf("port %d desc: %s\n", port_id, intf_info_st[port_id].description.c_str()); } @@ -1486,21 +1494,21 @@ int TRexPortAttr::set_led(uint8_t port_id, bool on){ } } -int TRexPortAttr::get_flow_ctrl(uint8_t port_id, enum rte_eth_fc_mode *mode) { +int TRexPortAttr::get_flow_ctrl(uint8_t port_id, int &mode) { int ret = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf_tmp); if (ret) { return ret; } - *mode = fc_conf_tmp.mode; + mode = (int) fc_conf_tmp.mode; return 0; } -int TRexPortAttr::set_flow_ctrl(uint8_t port_id, const enum rte_eth_fc_mode mode) { +int TRexPortAttr::set_flow_ctrl(uint8_t port_id, int mode) { int ret = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf_tmp); if (ret) { return ret; } - fc_conf_tmp.mode = mode; + fc_conf_tmp.mode = (enum rte_eth_fc_mode) mode; return rte_eth_dev_flow_ctrl_set(port_id, &fc_conf_tmp); } @@ -1558,12 +1566,38 @@ void TRexPortAttr::dump_link(uint8_t port_id, FILE *fd){ fprintf(fd,"promiscuous : %d \n",get_promiscuous(port_id)); } +void TRexPortAttr::update_device_info(uint8_t port_id){ + rte_eth_dev_info_get(port_id, &dev_info[port_id]); +} + +void TRexPortAttr::get_supported_speeds(uint8_t port_id, supp_speeds_t &supp_speeds){ + uint32_t speed_capa = dev_info[port_id].speed_capa; + if (speed_capa & ETH_LINK_SPEED_1G) + supp_speeds.push_back(ETH_SPEED_NUM_1G); + if (speed_capa & ETH_LINK_SPEED_10G) + supp_speeds.push_back(ETH_SPEED_NUM_10G); + if (speed_capa & ETH_LINK_SPEED_40G) + supp_speeds.push_back(ETH_SPEED_NUM_40G); + if (speed_capa & ETH_LINK_SPEED_100G) + supp_speeds.push_back(ETH_SPEED_NUM_100G); +} + void TRexPortAttr::update_link_status(uint8_t port_id){ rte_eth_link_get(port_id, &m_link[port_id]); } -void TRexPortAttr::update_link_status_nowait(uint8_t port_id){ - rte_eth_link_get_nowait(port_id, &m_link[port_id]); +bool TRexPortAttr::update_link_status_nowait(uint8_t port_id){ + rte_eth_link new_link; + bool changed = false; + rte_eth_link_get_nowait(port_id, &new_link); + if (new_link.link_speed != m_link[port_id].link_speed || + new_link.link_duplex != m_link[port_id].link_duplex || + new_link.link_autoneg != m_link[port_id].link_autoneg || + new_link.link_status != m_link[port_id].link_status) { + changed = true; + } + m_link[port_id] = new_link; + return changed; } int TRexPortAttr::add_mac(uint8_t port_id, char * mac){ @@ -2941,6 +2975,7 @@ public: void publish_async_data(bool sync_now, bool baseline = false); void publish_async_barrier(uint32_t key); + void publish_async_port_attr_changed(uint8_t port_id); void dump_stats(FILE *fd, CGlobalStats::DumpFormat format); @@ -3364,7 +3399,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) && !get_is_stateless()){ + if ( !is_all_links_are_up(true) /*&& !get_is_stateless()*/ ){ // disable start with link down for now dump_links_status(stdout); rte_exit(EXIT_FAILURE, " " " one of the link is down \n"); @@ -3597,7 +3632,6 @@ 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++) { @@ -4120,6 +4154,24 @@ CGlobalTRex::publish_async_barrier(uint32_t key) { m_zmq_publisher.publish_barrier(key); } +void +CGlobalTRex:: publish_async_port_attr_changed(uint8_t port_id) { + Json::Value data; + data["port_id"] = port_id; + + /* attributes */ + data["attr"]["speed"] = m_port_attr->get_link_speed(port_id); + data["attr"]["promiscuous"]["enabled"] = m_port_attr->get_promiscuous(port_id); + data["attr"]["link"]["up"] = m_port_attr->is_link_up(port_id); + int mode; + int ret = get_stateless_obj()->get_platform_api()->getPortAttrObj()->get_flow_ctrl(port_id, mode); + if (ret != 0) { + mode = -1; + } + data["attr"]["fc"]["mode"] = mode; + + m_zmq_publisher.publish_event(TrexPublisher::EVENT_PORT_ATTR_CHANGED, data); +} void CGlobalTRex::handle_slow_path() { @@ -4127,7 +4179,10 @@ CGlobalTRex::handle_slow_path() { // update speed, link up/down etc. for (int i=0; i<m_max_ports; i++) { - m_port_attr->update_link_status_nowait(i); + bool changed = m_port_attr->update_link_status_nowait(i); + if (changed) { + publish_async_port_attr_changed(i); + } } if ( CGlobalInfo::m_options.preview.get_no_keyboard() ==false ) { @@ -6334,12 +6389,6 @@ int TrexDpdkPlatformApi::get_xstats_names(uint8_t port_id, xstats_names_t &xstat 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; @@ -6386,10 +6435,6 @@ 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 { @@ -6409,6 +6454,7 @@ TrexDpdkPlatformApi::get_interface_info(uint8_t interface_id, intf_info_st &info memcpy(sw_macaddr, CGlobalInfo::m_options.get_dst_src_mac_addr(interface_id), 12); for (int i = 0; i < 6; i++) { + info.mac_info.hw_macaddr[i] = rte_mac_addr.addr_bytes[i]; info.mac_info.dst_macaddr[i] = sw_macaddr[i]; info.mac_info.src_macaddr[i] = sw_macaddr[6 + i]; @@ -6430,6 +6476,11 @@ TrexDpdkPlatformApi::publish_async_data_now(uint32_t key, bool baseline) const { } void +TrexDpdkPlatformApi::publish_async_port_attr_changed(uint8_t port_id) const { + g_trex.publish_async_port_attr_changed(port_id); +} + +void TrexDpdkPlatformApi::get_interface_stat_info(uint8_t interface_id, uint16_t &num_counters, uint16_t &capabilities) const { num_counters = CTRexExtendedDriverDb::Ins()->get_drv()->get_stat_counters_num(); capabilities = CTRexExtendedDriverDb::Ins()->get_drv()->get_rx_stat_capabilities(); @@ -6470,27 +6521,6 @@ 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); } -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_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 { g_trex.check_for_dp_messages(); } @@ -6530,6 +6560,10 @@ CFlowStatParser *TrexDpdkPlatformApi::get_flow_stat_parser() const { return CTRexExtendedDriverDb::Ins()->get_drv()->get_flow_stat_parser(); } +TRexPortAttr *TrexDpdkPlatformApi::getPortAttrObj() const { + return g_trex.m_port_attr; +} + /** * marks the control plane for a total server shutdown * diff --git a/src/pal/linux/rte_ethdev_includes.h b/src/pal/linux/rte_ethdev_includes.h new file mode 100644 index 00000000..de115d77 --- /dev/null +++ b/src/pal/linux/rte_ethdev_includes.h @@ -0,0 +1,23 @@ +struct rte_eth_link { + int link_autoneg; + int link_speed; + int link_duplex; + int link_status; +}; + + +enum rte_eth_fc_mode { +}; + +struct rte_eth_xstat { +}; + +struct rte_eth_xstat_name { +}; + +struct rte_eth_fc_conf { +}; + +struct rte_eth_dev_info { +}; + diff --git a/src/pal/linux_dpdk/rte_ethdev_includes.h b/src/pal/linux_dpdk/rte_ethdev_includes.h new file mode 100644 index 00000000..025ce8fc --- /dev/null +++ b/src/pal/linux_dpdk/rte_ethdev_includes.h @@ -0,0 +1 @@ +#include <rte_ethdev.h> diff --git a/src/publisher/trex_publisher.h b/src/publisher/trex_publisher.h index fb7226c4..522c8c69 100644 --- a/src/publisher/trex_publisher.h +++ b/src/publisher/trex_publisher.h @@ -49,6 +49,7 @@ public: EVENT_PORT_ACQUIRED = 5, EVENT_PORT_RELEASED = 6, EVENT_PORT_ERROR = 7, + EVENT_PORT_ATTR_CHANGED = 8, EVENT_SERVER_STOPPED = 100, diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp index f6b088a5..e4510a0a 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp @@ -295,6 +295,8 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value ¶ms, Json::Value &result) { string src_macaddr; string dst_macaddr; string pci_addr; + string description; + supp_speeds_t supp_speeds; int numa; TrexStatelessPort *port = main->get_port_by_id(i); @@ -302,10 +304,13 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value ¶ms, Json::Value &result) { port->get_macaddr(hw_macaddr, src_macaddr, dst_macaddr); port->get_pci_info(pci_addr, numa); + main->get_platform_api()->getPortAttrObj()->get_description(i, description); + main->get_platform_api()->getPortAttrObj()->get_supported_speeds(i, supp_speeds); section["ports"][i]["index"] = i; section["ports"][i]["driver"] = driver; + section["ports"][i]["description"] = description; section["ports"][i]["hw_macaddr"] = hw_macaddr; section["ports"][i]["src_macaddr"] = src_macaddr; section["ports"][i]["dst_macaddr"] = dst_macaddr; @@ -326,6 +331,14 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value ¶ms, Json::Value &result) { } section["ports"][i]["rx"]["counters"] = port->get_rx_count_num(); section["ports"][i]["speed"] = (uint16_t) speed / 1000; + section["ports"][i]["is_fc_supported"] = get_stateless_obj()->get_platform_api()->getPortAttrObj()->is_fc_change_supported(); + section["ports"][i]["is_led_supported"] = get_stateless_obj()->get_platform_api()->getPortAttrObj()->is_led_change_supported(); + section["ports"][i]["is_link_supported"] = get_stateless_obj()->get_platform_api()->getPortAttrObj()->is_link_change_supported(); + section["ports"][i]["is_virtual"] = get_stateless_obj()->get_platform_api()->getPortAttrObj()->is_virtual(); + section["ports"][i]["supp_speeds"] = Json::arrayValue; + for (int speed_id=0; speed_id<supp_speeds.size(); speed_id++) { + section["ports"][i]["supp_speeds"].append(supp_speeds[speed_id]); + } } @@ -349,22 +362,23 @@ TrexRpcCmdSetPortAttr::_run(const Json::Value ¶ms, Json::Value &result) { const Json::Value &attr = parse_object(params, "attr", result); int ret = 0; + bool changed = false; /* iterate over all attributes in the dict */ for (const std::string &name : attr.getMemberNames()) { if (name == "promiscuous") { bool enabled = parse_bool(attr[name], "enabled", result); - ret = get_stateless_obj()->get_platform_api()->set_promiscuous(port_id, enabled); + ret = get_stateless_obj()->get_platform_api()->getPortAttrObj()->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); + ret = get_stateless_obj()->get_platform_api()->getPortAttrObj()->set_link_up(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); + ret = get_stateless_obj()->get_platform_api()->getPortAttrObj()->set_led(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); + ret = get_stateless_obj()->get_platform_api()->getPortAttrObj()->set_flow_ctrl(port_id, mode); } else { generate_execute_err(result, "Not recognized attribute: " + name); break; @@ -376,8 +390,13 @@ TrexRpcCmdSetPortAttr::_run(const Json::Value ¶ms, Json::Value &result) { else if (ret) { generate_execute_err(result, "Error applying " + name + " attribute, return value: " + to_string(ret)); } + break; + } else { + changed = true; } - break; + } + if (changed) { + get_stateless_obj()->get_platform_api()->publish_async_port_attr_changed(port_id); } result["result"] = Json::objectValue; @@ -549,9 +568,17 @@ TrexRpcCmdGetPortStatus::_run(const Json::Value ¶ms, Json::Value &result) { result["result"]["owner"] = (port->get_owner().is_free() ? "" : port->get_owner().get_name()); result["result"]["state"] = port->get_state_as_string(); result["result"]["max_stream_id"] = port->get_max_stream_id(); + result["result"]["speed"] = get_stateless_obj()->get_platform_api()->getPortAttrObj()->get_link_speed(port_id); /* attributes */ - result["result"]["attr"]["promiscuous"]["enabled"] = get_stateless_obj()->get_platform_api()->get_promiscuous(port_id); + result["result"]["attr"]["promiscuous"]["enabled"] = get_stateless_obj()->get_platform_api()->getPortAttrObj()->get_promiscuous(port_id); + result["result"]["attr"]["link"]["up"] = get_stateless_obj()->get_platform_api()->getPortAttrObj()->is_link_up(port_id); + int mode; + int ret = get_stateless_obj()->get_platform_api()->getPortAttrObj()->get_flow_ctrl(port_id, mode); + if (ret != 0) { + mode = -1; + } + result["result"]["attr"]["fc"]["mode"] = mode; return (TREX_RPC_CMD_OK); } diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 8c6a1573..1a92b309 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -255,6 +255,11 @@ TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, /* caclulate the effective factor for DP */ double factor = calculate_effective_factor(mul, force); + /* zero factor */ + if (factor == 0) { + throw TrexException("Zero multiplier, nothing to send."); + } + StreamsFeeder feeder(this); /* compiler it */ @@ -278,7 +283,7 @@ TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, feeder.set_status(true); - /* generate a message to all the relevant DP cores to start transmitting */ + /* generate a message to all the relevant DP cores to stop transmitting */ assert(m_pending_async_stop_event == TrexDpPortEvents::INVALID_ID); m_pending_async_stop_event = m_dp_events.create_event(new AsyncStopEvent()); @@ -581,7 +586,7 @@ void TrexStatelessPort::get_properties(std::string &driver, uint32_t &speed) { driver = m_api_info.driver_name; - speed = platform_api->get_link_speed(m_port_id); + speed = platform_api->getPortAttrObj()->get_link_speed(m_port_id); } bool @@ -662,7 +667,7 @@ TrexStatelessPort::send_message_to_rx(TrexStatelessCpToRxMsgBase *msg) { uint64_t TrexStatelessPort::get_port_speed_bps() const { - return (uint64_t) platform_api->get_link_speed(m_port_id) * 1000 * 1000; + return (uint64_t) platform_api->getPortAttrObj()->get_link_speed(m_port_id) * 1000 * 1000; } static inline double diff --git a/src/stateless/cp/trex_streams_compiler.h b/src/stateless/cp/trex_streams_compiler.h index c944df4a..43fee09b 100644 --- a/src/stateless/cp/trex_streams_compiler.h +++ b/src/stateless/cp/trex_streams_compiler.h @@ -309,7 +309,7 @@ public: } double get_factor_pps(double req_pps) const { - if ( (req_pps - m_fixed.m_pps) <= 0 ) { + if ( (req_pps - m_fixed.m_pps) < 0 ) { std::stringstream ss; ss << "current stream configuration enforces a minimum rate of '" << m_fixed.m_pps << "' pps"; throw TrexException(ss.str()); @@ -319,7 +319,7 @@ public: } double get_factor_bps_l1(double req_bps_l1) const { - if ( (req_bps_l1 - m_fixed.m_bps_l1) <= 0 ) { + if ( (req_bps_l1 - m_fixed.m_bps_l1) < 0 ) { std::stringstream ss; ss << "current stream configuration enforces a minimum rate of '" << m_fixed.m_bps_l1 << "' BPS L1"; throw TrexException(ss.str()); @@ -329,7 +329,7 @@ public: } double get_factor_bps_l2(double req_bps_l2) const { - if ( (req_bps_l2 - m_fixed.m_bps_l2) <= 0 ) { + if ( (req_bps_l2 - m_fixed.m_bps_l2) < 0 ) { std::stringstream ss; ss << "current stream configuration enforces a minimum rate of '" << m_fixed.m_bps_l2 << "' BPS L2"; throw TrexException(ss.str()); diff --git a/src/trex_defs.h b/src/trex_defs.h index d8139a83..8a4bf664 100644 --- a/src/trex_defs.h +++ b/src/trex_defs.h @@ -55,5 +55,6 @@ 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; +typedef std::vector<uint32_t> supp_speeds_t; #endif diff --git a/src/trex_port_attr.h b/src/trex_port_attr.h index 037a3de3..cc267104 100755 --- a/src/trex_port_attr.h +++ b/src/trex_port_attr.h @@ -19,23 +19,33 @@ limitations under the License. #include <string> #include <vector> -#include <rte_ethdev.h> +#include "rte_ethdev_includes.h" #include "trex_defs.h" class TRexPortAttr { public: - TRexPortAttr(uint8_t total_ports, bool is_virtual = false) : total_ports(total_ports) { + TRexPortAttr(uint8_t total_ports, bool is_virtual, bool fc_change_allowed) : total_ports(total_ports) { flag_is_virtual = is_virtual; m_link.resize(total_ports); intf_info_st.resize(total_ports); + dev_info.resize(total_ports); + int tmp; + flag_is_fc_change_supported = fc_change_allowed && (get_flow_ctrl(0, tmp) != -ENOTSUP); + flag_is_led_change_supported = (set_led(0, true) != -ENOTSUP); + flag_is_link_change_supported = (set_link_up(0, true) != -ENOTSUP); + update_descriptions(); + for (int i=0; i<total_ports; i++) { + update_device_info(i); + } } /* UPDATES */ virtual void update_link_status(uint8_t port_id); - virtual void update_link_status_nowait(uint8_t port_id); + virtual bool update_link_status_nowait(uint8_t port_id); // returns true if the status was changed + virtual void update_device_info(uint8_t port_id); virtual void reset_xstats(uint8_t port_id); - virtual void update_info(); + virtual void update_descriptions(); /* GETTERS */ virtual bool get_promiscuous(uint8_t port_id); @@ -46,29 +56,36 @@ public: 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); + virtual int get_flow_ctrl(uint8_t port_id, int &mode); + virtual bool is_virtual() { return flag_is_virtual; } + virtual bool is_fc_change_supported() { return flag_is_fc_change_supported; } + virtual bool is_led_change_supported() { return flag_is_led_change_supported; } + virtual bool is_link_change_supported() { return flag_is_link_change_supported; } + virtual void get_description(uint8_t port_id, std::string &description) { description = intf_info_st[port_id].description; } + virtual void get_supported_speeds(uint8_t port_id, supp_speeds_t &supp_speeds); /* 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_flow_ctrl(uint8_t port_id, int 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<rte_eth_link> m_link; + std::vector<struct rte_eth_dev_info> dev_info; std::vector<struct rte_eth_xstat> xstats_values_tmp; std::vector<struct rte_eth_xstat_name> xstats_names_tmp; + bool flag_is_virtual; + bool flag_is_fc_change_supported; + bool flag_is_led_change_supported; + bool flag_is_link_change_supported; struct mac_cfg_st { uint8_t hw_macaddr[6]; |