summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/debug.cpp7
-rw-r--r--src/internal_api/trex_platform_api.h41
-rw-r--r--src/main_dpdk.cpp244
-rw-r--r--src/main_dpdk.h14
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_general.cpp86
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h8
-rw-r--r--src/rpc-server/trex_rpc_cmd.cpp2
-rw-r--r--src/rpc-server/trex_rpc_cmds_table.cpp2
-rw-r--r--src/stateless/cp/trex_stateless.h14
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp22
-rw-r--r--src/stateless/cp/trex_stateless_port.h9
-rw-r--r--src/trex_defs.h3
-rwxr-xr-xsrc/trex_port_attr.h91
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 &params, 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 &params, Json::Value &result) {
}
/**
+ * get port extended stats names (keys of dict)
+ *
+ */
+trex_rpc_cmd_rc_e
+TrexRpcCmdGetPortXStatsNames::_run(const Json::Value &params, 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 &params, 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 &params, 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 &params, 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__ */