diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/bp_sim.cpp | 14 | ||||
-rwxr-xr-x | src/bp_sim.h | 13 | ||||
-rw-r--r-- | src/main_dpdk.cpp | 72 | ||||
-rw-r--r-- | src/pre_test.cpp | 46 | ||||
-rw-r--r-- | src/publisher/trex_publisher.cpp | 10 | ||||
-rw-r--r-- | src/rpc-server/trex_rpc_req_resp_server.cpp | 2 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless.cpp | 9 | ||||
-rw-r--r-- | src/trex_client_config.cpp | 2 | ||||
-rw-r--r-- | src/trex_watchdog.cpp | 2 |
9 files changed, 127 insertions, 43 deletions
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index db273b18..62e8d822 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -177,8 +177,8 @@ physical_thread_id_t CPlatformSocketInfoNoConfig::thread_virt_to_phy(virtual_thr return (virt_id); } -bool CPlatformSocketInfoNoConfig::thread_phy_is_master(physical_thread_id_t phy_id){ - return (phy_id==0); +physical_thread_id_t CPlatformSocketInfoNoConfig::get_master_phy_id() { + return (0); } bool CPlatformSocketInfoNoConfig::thread_phy_is_rx(physical_thread_id_t phy_id){ @@ -402,8 +402,8 @@ physical_thread_id_t CPlatformSocketInfoConfig::thread_virt_to_phy(virtual_threa return ( m_thread_virt_to_phy[virt_id]); } -bool CPlatformSocketInfoConfig::thread_phy_is_master(physical_thread_id_t phy_id){ - return (m_platform->m_master_thread==phy_id?true:false); +physical_thread_id_t CPlatformSocketInfoConfig::get_master_phy_id() { + return m_platform->m_master_thread; } bool CPlatformSocketInfoConfig::thread_phy_is_rx(physical_thread_id_t phy_id){ @@ -481,6 +481,10 @@ bool CPlatformSocketInfo::thread_phy_is_master(physical_thread_id_t phy_id){ return ( m_obj->thread_phy_is_master(phy_id)); } +physical_thread_id_t CPlatformSocketInfo::get_master_phy_id() { + return ( m_obj->get_master_phy_id()); +} + bool CPlatformSocketInfo::thread_phy_is_rx(physical_thread_id_t phy_id) { return ( m_obj->thread_phy_is_rx(phy_id)); } @@ -4669,7 +4673,7 @@ void CFlowGenList::Dump(FILE *fd){ int i; for (i=0; i<(int)m_cap_gen.size(); i++) { CFlowGeneratorRec * lp=m_cap_gen[i]; - lp->Dump(stdout); + lp->Dump(fd); } } diff --git a/src/bp_sim.h b/src/bp_sim.h index f7a1e73c..cd0f6a13 100755 --- a/src/bp_sim.h +++ b/src/bp_sim.h @@ -957,10 +957,16 @@ public: /* return the map betwean virtual to phy id */ virtual physical_thread_id_t thread_virt_to_phy(virtual_thread_id_t virt_id)=0; - virtual bool thread_phy_is_master(physical_thread_id_t phy_id)=0; + + virtual physical_thread_id_t get_master_phy_id() = 0; virtual bool thread_phy_is_rx(physical_thread_id_t phy_id)=0; virtual void dump(FILE *fd)=0; + + bool thread_phy_is_master(physical_thread_id_t phy_id) { + return (get_master_phy_id() == phy_id); + } + }; class CPlatformSocketInfoNoConfig : public CPlatformSocketInfoBase { @@ -999,7 +1005,7 @@ public: /* return the map betwean virtual to phy id */ physical_thread_id_t thread_virt_to_phy(virtual_thread_id_t virt_id); - bool thread_phy_is_master(physical_thread_id_t phy_id); + physical_thread_id_t get_master_phy_id(); bool thread_phy_is_rx(physical_thread_id_t phy_id); virtual void dump(FILE *fd); @@ -1045,7 +1051,7 @@ public: /* return the map betwean virtual to phy id */ physical_thread_id_t thread_virt_to_phy(virtual_thread_id_t virt_id); - bool thread_phy_is_master(physical_thread_id_t phy_id); + physical_thread_id_t get_master_phy_id(); bool thread_phy_is_rx(physical_thread_id_t phy_id); public: @@ -1110,6 +1116,7 @@ public: physical_thread_id_t thread_virt_to_phy(virtual_thread_id_t virt_id); bool thread_phy_is_master(physical_thread_id_t phy_id); + physical_thread_id_t get_master_phy_id(); bool thread_phy_is_rx(physical_thread_id_t phy_id); void dump(FILE *fd); diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index fbd55173..16fc2203 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -128,7 +128,7 @@ 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]; - +static char global_master_id_str[10]; class CTRexExtendedDriverBase { public: @@ -168,6 +168,14 @@ public: virtual CFlowStatParser *get_flow_stat_parser(); virtual int set_rcv_all(CPhyEthIF * _if, bool set_on)=0; virtual TRexPortAttr * create_port_attr(uint8_t port_id) = 0; + + /* Does this NIC type support automatic packet dropping in case of a link down? + in case it is supported the packets will be dropped, else there would be a back pressure to tx queues + this interface is used as a workaround to let TRex work without link in stateless mode, driver that + does not support that will be failed at init time because it will cause watchdog due to watchdog hang */ + virtual bool drop_packets_incase_of_linkdown() { + return (false); + } }; @@ -363,6 +371,10 @@ private: virtual int add_del_eth_type_rule(uint8_t port_id, enum rte_filter_op op, uint16_t eth_type); virtual int configure_rx_filter_rules_statefull(CPhyEthIF * _if); + virtual bool drop_packets_incase_of_linkdown() { + return (true); + } + private: uint8_t m_if_per_card; }; @@ -3412,9 +3424,15 @@ int CGlobalTRex::ixgbe_start(void){ get_ex_drv()->wait_for_stable_link(); 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"); + + /* temporary solution for trex-192 issue, solve the case for X710/XL710, will work for both Statless and Stateful */ + if ( get_ex_drv()->drop_packets_incase_of_linkdown() ){ + printf(" WARNING : there is no link on one of the ports, driver support auto drop in case of link down - continue\n"); + }else{ + dump_links_status(stdout); + rte_exit(EXIT_FAILURE, " " + " one of the link is down \n"); + } } } else { get_ex_drv()->wait_after_link_up(); @@ -4391,6 +4409,8 @@ void CGlobalTRex::shutdown() { int CGlobalTRex::run_in_master() { + //rte_thread_setname(pthread_self(), "TRex Control"); + if ( get_is_stateless() ) { m_trex_stateless->launch_control_plane(); } @@ -4441,6 +4461,8 @@ int CGlobalTRex::run_in_master() { int CGlobalTRex::run_in_rx_core(void){ + rte_thread_setname(pthread_self(), "TRex RX"); + if (get_is_stateless()) { m_sl_rx_running = true; m_rx_sl.start(); @@ -4457,7 +4479,9 @@ int CGlobalTRex::run_in_rx_core(void){ int CGlobalTRex::run_in_core(virtual_thread_id_t virt_core_id){ std::stringstream ss; - ss << "DP core " << int(virt_core_id); + + ss << "Trex DP core " << int(virt_core_id); + rte_thread_setname(pthread_self(), ss.str().c_str()); CPreviewMode *lp=&CGlobalInfo::m_options.preview; if ( lp->getSingleCore() && @@ -5069,25 +5093,28 @@ int update_dpdk_args(void){ } /* set the DPDK options */ - global_dpdk_args_num =7; + global_dpdk_args_num = 0; - global_dpdk_args[0]=(char *)"xx"; - global_dpdk_args[1]=(char *)"-c"; - global_dpdk_args[2]=(char *)global_cores_str; - global_dpdk_args[3]=(char *)"-n"; - global_dpdk_args[4]=(char *)"4"; + global_dpdk_args[global_dpdk_args_num++]=(char *)"xx"; + global_dpdk_args[global_dpdk_args_num++]=(char *)"-c"; + global_dpdk_args[global_dpdk_args_num++]=(char *)global_cores_str; + global_dpdk_args[global_dpdk_args_num++]=(char *)"-n"; + global_dpdk_args[global_dpdk_args_num++]=(char *)"4"; if ( CGlobalInfo::m_options.preview.getVMode() == 0 ) { - global_dpdk_args[5]=(char *)"--log-level"; + global_dpdk_args[global_dpdk_args_num++]=(char *)"--log-level"; snprintf(global_loglevel_str, sizeof(global_loglevel_str), "%d", 4); - global_dpdk_args[6]=(char *)global_loglevel_str; + global_dpdk_args[global_dpdk_args_num++]=(char *)global_loglevel_str; }else{ - global_dpdk_args[5]=(char *)"--log-level"; + global_dpdk_args[global_dpdk_args_num++]=(char *)"--log-level"; snprintf(global_loglevel_str, sizeof(global_loglevel_str), "%d", CGlobalInfo::m_options.preview.getVMode()+1); - global_dpdk_args[6]=(char *)global_loglevel_str; + global_dpdk_args[global_dpdk_args_num++]=(char *)global_loglevel_str; } - global_dpdk_args_num = 7; + global_dpdk_args[global_dpdk_args_num++] = (char *)"--master-lcore"; + + snprintf(global_master_id_str, sizeof(global_master_id_str), "%u", lpsock->get_master_phy_id()); + global_dpdk_args[global_dpdk_args_num++] = global_master_id_str; /* add white list */ if (lpop->m_run_mode == CParserOption::RUN_MODE_DUMP_INFO and lpop->dump_interfaces.size()) { @@ -5178,6 +5205,7 @@ void dump_interfaces_info() { int main_test(int argc , char * argv[]){ + utl_termio_init(); int ret; @@ -5233,6 +5261,12 @@ int main_test(int argc , char * argv[]){ return (-1); } + /* set affinity to the master core as default */ + cpu_set_t mask; + CPU_ZERO(&mask); + CPU_SET(CGlobalInfo::m_socket.get_master_phy_id(), &mask); + pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask); + ret = rte_eal_init(global_dpdk_args_num, (char **)global_dpdk_args); if (ret < 0){ printf(" You might need to run ./trex-cfg once \n"); @@ -6218,8 +6252,10 @@ int CTRexExtendedDriverBase40G::verify_fw_ver(int port_id) { ret = rte_eth_get_fw_ver(port_id, &version); if (ret == 0) { - printf("port %d: FW ver %02d.%02d.%02d\n", port_id, ((version >> 12) & 0xf), ((version >> 4) & 0xff) - ,(version & 0xf)); + if (CGlobalInfo::m_options.preview.getVMode() >= 1) { + printf("port %d: FW ver %02d.%02d.%02d\n", port_id, ((version >> 12) & 0xf), ((version >> 4) & 0xff) + ,(version & 0xf)); + } if ((((version >> 12) & 0xf) < 5) || ((((version >> 12) & 0xf) == 5) && ((version >> 4 & 0xff) == 0) && ((version & 0xf) < 4))) { diff --git a/src/pre_test.cpp b/src/pre_test.cpp index 278db98b..130d076d 100644 --- a/src/pre_test.cpp +++ b/src/pre_test.cpp @@ -114,9 +114,10 @@ int CPretest::handle_rx(int port_id, int queue_id) { do { cnt = rte_eth_rx_burst(port_id, queue_id, rx_pkts, sizeof(rx_pkts)/sizeof(rx_pkts[0])); tries++; - + bool free_pkt; for (i = 0; i < cnt; i++) { rte_mbuf_t * m = rx_pkts[i]; + free_pkt = true; int pkt_size = rte_pktmbuf_pkt_len(m); uint8_t *p = rte_pktmbuf_mtod(m, uint8_t *); ArpHdr *arp; @@ -125,9 +126,8 @@ int CPretest::handle_rx(int port_id, int queue_id) { m_port_info[port_id].m_stats.m_rx_arp++; if (arp->m_arp_op == htons(ArpHdr::ARP_HDR_OP_REQUEST)) { if (verbose >= 3) { - fprintf(stdout, "RX ARP request on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id - , ntohl(arp->m_arp_sip) - , ntohl(arp->m_arp_tip)); + fprintf(stdout, "RX ARP request on port %d queue %d sip:0x%08x tip:0x%08x\n" + , port_id, queue_id, ntohl(arp->m_arp_sip), ntohl(arp->m_arp_tip)); } // is this request for our IP? if (ntohl(arp->m_arp_tip) == port->m_ip) { @@ -142,14 +142,45 @@ int CPretest::handle_rx(int port_id, int queue_id) { m_port_info[sent_port_id].m_state = CPretestPortInfo::RESOLVE_DONE; m_port_info[sent_port_id].m_is_loopback = true; } + } else { + // Not our request. Answer. + free_pkt = false; // We use the same mbuf to send response. Don't free it twice. + arp->m_arp_op = htons(ArpHdr::ARP_HDR_OP_REPLY); + uint32_t tmp_ip = arp->m_arp_sip; + arp->m_arp_sip = arp->m_arp_tip; + arp->m_arp_tip = tmp_ip; + memcpy((uint8_t *)&arp->m_arp_tha, (uint8_t *)&arp->m_arp_sha, ETHER_ADDR_LEN); + memcpy((uint8_t *)&arp->m_arp_sha, port->m_src_mac, ETHER_ADDR_LEN); + EthernetHeader *m_ether = (EthernetHeader *)p; + memcpy((uint8_t *)&m_ether->myDestination, (uint8_t *)&m_ether->mySource, ETHER_ADDR_LEN); + memcpy((uint8_t *)&m_ether->mySource, (uint8_t *)port->m_src_mac, ETHER_ADDR_LEN); + int num_sent = rte_eth_tx_burst(port_id, 0, &m, 1); + if (num_sent < 1) { + fprintf(stderr, "Failed sending ARP reply to port:%d\n", port_id); + rte_pktmbuf_free(m); + } else { + fprintf(stdout, "TX ARP reply on port:%d sip:0x%08x, tip:0x%08x\n" + , port_id ,htonl(arp->m_arp_sip), htonl(arp->m_arp_tip)); + m_port_info[port_id].m_stats.m_tx_arp++; + } } } else { - // ARP request not to our IP. At the moment, we ignore this. + // ARP request not to our IP. + if ((ntohl(arp->m_arp_tip) == port->m_def_gw) && (ntohl(arp->m_arp_sip) == port->m_def_gw)) { + // sip and tip equals def_gw, meaning we got gratitues ARP. + port->set_dst_mac((uint8_t *)&arp->m_arp_sha); + } } } else { if (arp->m_arp_op == htons(ArpHdr::ARP_HDR_OP_REPLY)) { if (verbose >= 3) { - fprintf(stdout, "RX ARP response on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id + bool is_grat = false; + if (arp->m_arp_sip == arp->m_arp_tip) { + is_grat = true; + } + fprintf(stdout, "RX %s on port %d queue %d sip:0x%08x tip:0x%08x\n" + , is_grat ? "grat ARP" : "ARP reply" + , port_id, queue_id , ntohl(arp->m_arp_sip) , ntohl(arp->m_arp_tip)); } @@ -160,7 +191,8 @@ int CPretest::handle_rx(int port_id, int queue_id) { } } } - rte_pktmbuf_free(m); + if (free_pkt) + rte_pktmbuf_free(m); } } while ((cnt != 0) && (tries < 1000)); diff --git a/src/publisher/trex_publisher.cpp b/src/publisher/trex_publisher.cpp index 67670593..224604e9 100644 --- a/src/publisher/trex_publisher.cpp +++ b/src/publisher/trex_publisher.cpp @@ -33,6 +33,8 @@ limitations under the License. bool TrexPublisher::Create(uint16_t port, bool disable){ + char thread_name[256]; + if (disable) { return (true); } @@ -42,7 +44,15 @@ TrexPublisher::Create(uint16_t port, bool disable){ show_zmq_last_error("can't connect to ZMQ library"); } + /* change the pthread name temporarly for the socket creation */ + pthread_getname_np(pthread_self(), thread_name, sizeof(thread_name)); + pthread_setname_np(pthread_self(), "Trex Publisher"); + m_publisher = zmq_socket (m_context, ZMQ_PUB); + + /* restore it */ + pthread_setname_np(pthread_self(), thread_name); + if ( m_context == 0 ) { show_zmq_last_error("can't create ZMQ socket"); } diff --git a/src/rpc-server/trex_rpc_req_resp_server.cpp b/src/rpc-server/trex_rpc_req_resp_server.cpp index e0e7635c..28bf1d80 100644 --- a/src/rpc-server/trex_rpc_req_resp_server.cpp +++ b/src/rpc-server/trex_rpc_req_resp_server.cpp @@ -56,6 +56,8 @@ void TrexRpcServerReqRes::_rpc_thread_cb() { std::stringstream ss; int zmq_rc; + pthread_setname_np(pthread_self(), "Trex ZMQ sync"); + m_monitor.create(m_name, 1); TrexWatchDog::getInstance().register_monitor(&m_monitor); diff --git a/src/stateless/cp/trex_stateless.cpp b/src/stateless/cp/trex_stateless.cpp index 6029cbd5..0a7f8533 100644 --- a/src/stateless/cp/trex_stateless.cpp +++ b/src/stateless/cp/trex_stateless.cpp @@ -112,15 +112,6 @@ void TrexStateless::shutdown() { void TrexStateless::launch_control_plane() { - /* pin this process to the current running CPU - any new thread will be called on the same CPU - (control plane restriction) - */ - cpu_set_t mask; - CPU_ZERO(&mask); - CPU_SET(sched_getcpu(), &mask); - sched_setaffinity(0, sizeof(mask), &mask); - /* start RPC server */ m_rpc_server->start(); } diff --git a/src/trex_client_config.cpp b/src/trex_client_config.cpp index b56037ea..ad71d38e 100644 --- a/src/trex_client_config.cpp +++ b/src/trex_client_config.cpp @@ -127,7 +127,7 @@ ClientCfgDB::parse_single_group(YAMLParserWrapper &parser, const YAML::Node &nod void ClientCfgDB::parse_dir(YAMLParserWrapper &parser, const YAML::Node &node, ClientCfgDir &dir) { if (node.FindValue("src_mac")) { - dir.set_dst_mac_addr(parser.parse_mac_addr(node, "src_mac")); + dir.set_src_mac_addr(parser.parse_mac_addr(node, "src_mac")); } if (node.FindValue("dst_mac")) { diff --git a/src/trex_watchdog.cpp b/src/trex_watchdog.cpp index 88711b7a..9b6f5865 100644 --- a/src/trex_watchdog.cpp +++ b/src/trex_watchdog.cpp @@ -218,6 +218,8 @@ void TrexWatchDog::stop() { */ void TrexWatchDog::_main() { + pthread_setname_np(pthread_self(), "Trex Watchdog"); + assert(m_enable == true); /* start main loop */ |