summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dpdk/drivers/net/virtio/virtio_ethdev.c2
-rw-r--r--src/dpdk/drivers/net/vmxnet3/vmxnet3_ethdev.c2
-rw-r--r--src/internal_api/trex_platform_api.h45
-rw-r--r--src/main_dpdk.cpp138
-rw-r--r--src/pal/linux/rte_ethdev_includes.h23
-rw-r--r--src/pal/linux_dpdk/rte_ethdev_includes.h1
-rw-r--r--src/publisher/trex_publisher.h1
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_general.cpp39
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp11
-rw-r--r--src/stateless/cp/trex_streams_compiler.h6
-rw-r--r--src/trex_defs.h1
-rwxr-xr-xsrc/trex_port_attr.h39
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 &params, 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 &params, 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 &params, 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 &params, 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 &params, 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 &params, 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];