summaryrefslogtreecommitdiffstats
path: root/src/main_dpdk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main_dpdk.cpp')
-rwxr-xr-xsrc/main_dpdk.cpp1145
1 files changed, 652 insertions, 493 deletions
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index a0af9fdf..15d7451e 100755
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -51,11 +51,17 @@ limitations under the License.
#include <rte_mbuf.h>
#include <rte_random.h>
#include "bp_sim.h"
+#include "latency.h"
#include "os_time.h"
#include <common/arg/SimpleGlob.h>
#include <common/arg/SimpleOpt.h>
#include <common/basic_utils.h>
+
#include <stateless/cp/trex_stateless.h>
+#include <stateless/dp/trex_stream_node.h>
+#include <publisher/trex_publisher.h>
+#include <stateless/messaging/trex_stateless_messaging.h>
+
#include <../linux_dpdk/version.h>
extern "C" {
@@ -72,7 +78,9 @@ extern "C" {
#include "utl_term_io.h"
#include "msg_manager.h"
#include "platform_cfg.h"
+#include "latency.h"
+#include <internal_api/trex_platform_api.h>
#define RX_CHECK_MIX_SAMPLE_RATE 8
#define RX_CHECK_MIX_SAMPLE_RATE_1G 2
@@ -104,8 +112,6 @@ extern "C" int vmxnet3_xmit_set_callback(rte_mbuf_convert_to_one_seg_t cb);
#define RTE_TEST_TX_DESC_DEFAULT 512
#define RTE_TEST_RX_DESC_DROP 0
-
-
static inline int get_vm_one_queue_enable(){
return (CGlobalInfo::m_options.preview.get_vm_one_queue_enable() ?1:0);
}
@@ -114,15 +120,15 @@ static inline int get_is_latency_thread_enable(){
return (CGlobalInfo::m_options.is_latency_enabled() ?1:0);
}
-
-
struct port_cfg_t;
class CPhyEthIF;
class CPhyEthIFStats ;
-
class CTRexExtendedDriverBase {
public:
+
+ virtual TrexPlatformApi::driver_speed_e get_driver_speed() = 0;
+
virtual int get_min_sample_rate(void)=0;
virtual void update_configuration(port_cfg_t * cfg)=0;
virtual void update_global_config_fdir(port_cfg_t * cfg)=0;
@@ -149,6 +155,10 @@ public:
CTRexExtendedDriverBase1G(){
}
+ TrexPlatformApi::driver_speed_e get_driver_speed() {
+ return TrexPlatformApi::SPEED_1G;
+ }
+
static CTRexExtendedDriverBase * create(){
return ( new CTRexExtendedDriverBase1G() );
}
@@ -187,6 +197,10 @@ public:
CGlobalInfo::m_options.preview.set_vm_one_queue_enable(true);
}
+ TrexPlatformApi::driver_speed_e get_driver_speed() {
+ return TrexPlatformApi::SPEED_1G;
+ }
+
static CTRexExtendedDriverBase * create(){
return ( new CTRexExtendedDriverBase1GVm() );
}
@@ -225,6 +239,11 @@ class CTRexExtendedDriverBase10G : public CTRexExtendedDriverBase {
public:
CTRexExtendedDriverBase10G(){
}
+
+ TrexPlatformApi::driver_speed_e get_driver_speed() {
+ return TrexPlatformApi::SPEED_10G;
+ }
+
static CTRexExtendedDriverBase * create(){
return ( new CTRexExtendedDriverBase10G() );
}
@@ -257,6 +276,10 @@ public:
CTRexExtendedDriverBase40G(){
}
+ TrexPlatformApi::driver_speed_e get_driver_speed() {
+ return TrexPlatformApi::SPEED_40G;
+ }
+
static CTRexExtendedDriverBase * create(){
return ( new CTRexExtendedDriverBase40G() );
}
@@ -299,6 +322,11 @@ public:
class CTRexExtendedDriverDb {
public:
+
+ const std::string & get_driver_name() {
+ return m_driver_name;
+ }
+
bool is_driver_exists(std::string name);
@@ -407,12 +435,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 ;
@@ -421,9 +443,6 @@ 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,
@@ -458,6 +477,7 @@ enum { OPT_HELP,
OPT_IPV6,
OPT_LEARN,
OPT_LEARN_VERIFY,
+ OPT_L_PKT_MODE,
OPT_NO_FLOW_CONTROL,
OPT_RX_CHECK_HOPS,
OPT_MAC_FILE,
@@ -470,9 +490,6 @@ enum { OPT_HELP,
};
-
-
-
/* these are the argument types:
SO_NONE -- no argument needed
SO_REQ_SEP -- single required argument
@@ -520,6 +537,7 @@ static CSimpleOpt::SOption parser_options[] =
{ OPT_IPV6, "--ipv6", SO_NONE },
{ OPT_LEARN, "--learn", SO_NONE },
{ OPT_LEARN_VERIFY, "--learn-verify", SO_NONE },
+ { OPT_L_PKT_MODE, "--l-pkt-mode", SO_REQ_SEP },
{ OPT_NO_FLOW_CONTROL, "--no-flow-control", SO_NONE },
{ OPT_VLAN, "--vlan", SO_NONE },
{ OPT_MAC_FILE, "--mac", SO_REQ_SEP },
@@ -549,19 +567,17 @@ static int usage(){
printf(" --mac [file] : YAML file with <client ip, mac addr> configuration \n");
printf(" \n\n");
- printf(" -r : realtime enable \n");
- printf(" \n\n");
- printf(" -c [number of cores] : 1 ,2,3,4,5 numnber of dual cores + master 1 means 1 master and 2 cores \n");
+ printf(" -c [number of threads] : default is 1. number of threads to allocate for each dual ports. \n");
printf(" \n");
- printf(" -s : run only one data path core\n");
+ printf(" -s : run only one data path core. for debug\n");
printf(" \n");
- printf(" --flip : flow will be sent from client->server and server->client for maximum throughput \n");
+ printf(" --flip : flow will be sent from client->server and server->client for maximum throughput \n");
printf(" \n");
- printf(" -p : flow-flip , send all packets flow from the same interface base of client ip \n");
+ printf(" -p : flow-flip , send all flow packets from the same interface base of client ip \n");
printf(" -e : like -p but comply to the generator rules \n");
printf(" \n");
- printf(" -l [pkt/sec] : run laterncy daemon in this rate \n");
+ printf(" -l [pkt/sec] : run latency daemon in this rate \n");
printf(" e.g -l 1000 run 1000 pkt/sec from each interface , zero mean to disable latency check \n");
printf(" --lm : latency mask \n");
printf(" 0x1 only port 0 will send traffic \n");
@@ -569,20 +585,18 @@ static int usage(){
printf(" \n");
- printf(" --limit-ports : limit number of ports , must be even e.g 2,4 \n");
+ printf(" --limit-ports : limit number of ports, must be even e.g. 2,4 \n");
printf(" \n");
- printf(" --nc : if set will not close all the flow , faster \n");
+ printf(" --nc : If set, will not wait for all the flows to be closed, terminate faster- see manual for more information \n");
printf(" \n");
- printf(" -d : duration of the test in sec \n");
+ printf(" -d : duration of the test in sec. look for --nc \n");
printf(" \n");
- printf(" -pm : platform factor , in case you have splitter in the setup you can multiply the total results in this factor \n");
+ printf(" -pm : platform factor ,in case you have splitter in the setup you can multiply the total results in this factor \n");
printf(" e.g --pm 2.0 will multiply all the results bps in this factor \n");
printf(" \n");
printf(" -pubd : disable monitors publishers \n");
- printf(" -m : factor of bandwidth \n");
- printf(" \n");
- printf(" -1g : 1G trex \n");
+ printf(" -m : factor of bandwidth \n");
printf(" \n");
printf(" -k [sec] : run latency test before starting the test. it will wait for x sec sending packet and x sec after that \n");
printf(" \n");
@@ -592,12 +606,16 @@ static int usage(){
printf(" you can copy this file to /etc/trex_cfg.yaml \n");
printf(" \n");
- printf(" --ipv6 : work in ipv6 mode \n");
+ printf(" --ipv6 : work in ipv6 mode\n");
printf(" --learn : Work in NAT environments, learn the dynamic NAT translation and ALG \n");
printf(" --learn-verify : Learn the translation, but intended for verification of the mechanism in cases that NAT does not exist \n");
printf(" \n");
-
+ printf(" --l-pkt-mode [0-3] : Set mode for sending latency packets.\n");
+ printf(" 0 (default) send SCTP packets \n");
+ printf(" 1 Send ICMP request packets \n");
+ printf(" 2 Send ICMP requests from client side, and response from server side (for working with firewall) \n");
+ printf(" 3 Send ICMP requests with sequence ID 0 from both sides \n");
printf(" -v [1-3] : verbose mode ( works only on the debug image ! ) \n");
printf(" 1 show only stats \n");
printf(" 2 run preview do not write to file \n");
@@ -607,17 +625,17 @@ static int usage(){
printf(" Warning : This program can generate huge-files (TB ) watch out! try this only on local drive \n");
printf(" \n");
printf(" \n");
- printf(" --rx-check [sample] : enable rx check thread , using this thread we sample flows 1/sample and check order,latency and more \n");
+ printf(" --rx-check [sample] : enable rx check thread, using this thread we sample flows 1/sample and check order,latency and more \n");
printf(" this feature consume another thread \n");
printf(" \n");
- printf(" --hops [hops] : If rx check is enabled, the hop number can be assigned. The default number of hops is 1\n");
- printf(" --iom [mode] : io mode for interactive mode [0- silent, 1- normal , 2- short] \n");
+ printf(" --hops [hops] : If rx check is enabled, the hop number can be assigned. The default number of hops is 1\n");
+ printf(" --iom [mode] : io mode for interactive mode [0- silent, 1- normal , 2- short] \n");
printf(" this feature consume another thread \n");
printf(" \n");
- printf(" --no-key : daemon mode, don't get input from keyboard \n");
- printf(" --no-flow-control : In default TRex disables flow-control using this flag it does not touch it \n");
- printf(" --prefix : for multi trex, each instance should have a different name \n");
- printf(" --mac-spread : Spread the destination mac-order by this factor. e.g 2 will generate the traffic to 2 devices DEST-MAC ,DEST-MAC+1 \n");
+ printf(" --no-key : daemon mode, don't get input from keyboard \n");
+ printf(" --no-flow-control : In default TRex disables flow-control using this flag it does not touch it \n");
+ printf(" --prefix : for multi trex, each instance should have a different name \n");
+ printf(" --mac-spread : Spread the destination mac-order by this factor. e.g 2 will generate the traffic to 2 devices DEST-MAC ,DEST-MAC+1 \n");
printf(" maximum is up to 128 devices \n");
@@ -628,7 +646,7 @@ static int usage(){
printf(" \n");
printf(" -o [capfile_name] simulate trex into pcap file \n");
printf(" --pcap export the file in pcap mode \n");
- printf(" t-rex-64 -d 10 -f cfg.yaml -o my.pcap --pcap # export 10 sec of what Trex will do on real-time to a file my.pcap \n");
+ printf(" bp-sim-64 -d 10 -f cfg.yaml -o my.pcap --pcap # export 10 sec of what Trex will do on real-time to a file my.pcap \n");
printf(" --vm-sim : simulate vm with driver of one input queue and one output queue \n");
printf(" \n");
printf(" Examples: ");
@@ -660,7 +678,7 @@ static int usage(){
printf(" limitations under the License. \n");
printf(" \n");
printf(" Open Source Components / Libraries \n");
- printf(" DPDK (BSD) \n");
+ printf(" DPDK (BSD) \n");
printf(" YAML-CPP (BSD) \n");
printf(" JSONCPP (MIT) \n");
printf(" \n");
@@ -671,6 +689,7 @@ static int usage(){
printf(" User : %s \n",VERSION_USER);
printf(" Date : %s , %s \n",get_build_date(),get_build_time());
printf(" Uuid : %s \n",VERSION_UIID);
+ printf(" Git SHA : %s \n",VERSION_GIT_SHA);
return (0);
}
@@ -686,12 +705,13 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t
CSimpleOpt args(argc, argv, parser_options);
bool latency_was_set=false;
+ (void)latency_was_set;
+
int a=0;
int node_dump=0;
po->preview.setFileWrite(true);
po->preview.setRealTime(true);
- int res1;
uint32_t tmp_data;
po->m_run_mode = CParserOption::RUN_MODE_INVALID;
@@ -756,6 +776,11 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t
po->preview.set_lean_and_verify_mode_enable(true);
break;
+ case OPT_L_PKT_MODE :
+ sscanf(args.OptionArg(),"%d", &tmp_data);
+ po->m_l_pkt_mode=(uint8_t)tmp_data;
+ break;
+
case OPT_REAL_TIME :
printf(" warning -r is deprecated, real time is not needed any more , it is the default \n");
po->preview.setRealTime(true);
@@ -889,7 +914,7 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t
}
if (po->preview.get_is_rx_check_enable() && ( po->is_latency_disabled() ) ) {
- printf(" rx check must be enable with latency check. try adding '-l 1000' \n");
+ printf(" rx check must be enabled with latency check. try adding '-l 1000' \n");
return -1;
}
@@ -902,7 +927,7 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t
uint32_t cores=po->preview.getCores();
if ( cores > ((BP_MAX_CORES)/2-1) ) {
- printf(" ERROR maximum cores are : %d \n",((BP_MAX_CORES)/2-1));
+ printf(" ERROR maximum supported cores are : %d \n",((BP_MAX_CORES)/2-1));
return -1;
}
@@ -928,40 +953,30 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t
}
}
- return 0;
-}
-
-
-int main_test(int argc , char * argv[]);
-
-
-
-
-void delay(int msec){
-
- if (msec == 0)
- {//user that requested that probebly wanted the minimal delay
- //but because of scaling problem he have got 0 so we will give the min delay
- //printf("\n\n\nERROR-Task delay ticks == 0 found in task %s task id = %d\n\n\n\n",
- // SANB_TaskName(SANB_TaskIdSelf()), SANB_TaskIdSelf());
- msec =1;
+ if ( get_is_stateless() ) {
+ if ( po->preview.get_is_rx_check_enable() ) {
+ parse_err("Rx check is not supported with interactive mode ");
+ }
- }
+ if ( (! po->is_latency_disabled()) || (po->preview.getOnlyLatency()) ){
+ parse_err("Latecny check is not supported with interactive mode ");
+ }
- struct timespec time1, remain; // 2 sec max delay
- time1.tv_sec=msec/1000;
- time1.tv_nsec=(msec - (time1.tv_sec*1000))*1000000;
+ if ( po->preview.getSingleCore() ){
+ parse_err("single core is not supported with interactive mode ");
+ }
- nanosleep(&time1,&remain);
+ }
+ return 0;
}
-
-static const char * default_argv[] = {"xx","-c", "0x7", "-n","2","-b","0000:0b:01.01"};
-static int argv_num = 7;
-
+int main_test(int argc , char * argv[]);
+//static const char * default_argv[] = {"xx","-c", "0x7", "-n","2","-b","0000:0b:01.01"};
+//static int argv_num = 7;
+
#define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */
@@ -1145,8 +1160,8 @@ void CPhyEthIFStats::Clear(){
void CPhyEthIFStats::DumpAll(FILE *fd){
- #define DP_A4(f) printf(" %-40s : %llu \n",#f,f)
- #define DP_A(f) if (f) printf(" %-40s : %llu \n",#f,f)
+ #define DP_A4(f) printf(" %-40s : %llu \n",#f, (unsigned long long)f)
+ #define DP_A(f) if (f) printf(" %-40s : %llu \n",#f, (unsigned long long)f)
DP_A4(opackets);
DP_A4(obytes);
DP_A4(ipackets);
@@ -1185,7 +1200,7 @@ public:
m_port_id = portid;
m_last_rx_rate = 0.0;
m_last_tx_rate = 0.0;
- m_last_pps=0.0;
+ m_last_tx_pps = 0.0;
return (true);
}
void Delete();
@@ -1261,8 +1276,12 @@ public:
return (m_last_rx_rate);
}
- float get_last_pps_rate(){
- return (m_last_pps);
+ float get_last_tx_pps_rate(){
+ return (m_last_tx_pps);
+ }
+
+ float get_last_rx_pps_rate(){
+ return (m_last_rx_pps);
}
CPhyEthIFStats & get_stats(){
@@ -1315,12 +1334,14 @@ private:
CBwMeasure m_bw_tx;
CBwMeasure m_bw_rx;
CPPSMeasure m_pps_tx;
+ CPPSMeasure m_pps_rx;
CPhyEthIFStats m_stats;
- float m_last_rx_rate;
float m_last_tx_rate;
- float m_last_pps;
+ float m_last_rx_rate;
+ float m_last_tx_pps;
+ float m_last_rx_pps;
public:
struct rte_eth_dev_info m_dev_info;
};
@@ -1426,11 +1447,11 @@ void CPhyEthIF::configure(uint16_t nb_rx_queue,
/*
-rx-queue 0 - default- all traffic no SCTP
+rx-queue 0 - default- all traffic not goint to queue 1
will be drop as queue is disable
-rx-queue 1 - SCTP traffic will go to here
+rx-queue 1 - Latency measurement packets will go here
pci_reg_write(IXGBE_L34T_IMIR(0),(1<<21));
@@ -1615,10 +1636,6 @@ void CPhyEthIF::macaddr_get(struct ether_addr *mac_addr){
void CPhyEthIF::get_stats_1g(CPhyEthIFStats *stats){
- int i;
- uint64_t t=0;
-
-
stats->ipackets += pci_reg_read(E1000_GPRC) ;
stats->ibytes += (pci_reg_read(E1000_GORCL) );
@@ -1656,7 +1673,8 @@ void CPhyEthIF::get_stats_1g(CPhyEthIFStats *stats){
m_last_tx_rate = m_bw_tx.add(stats->obytes);
m_last_rx_rate = m_bw_rx.add(stats->ibytes);
- m_last_pps = m_pps_tx.add(stats->opackets);
+ m_last_tx_pps = m_pps_tx.add(stats->opackets);
+ m_last_rx_pps = m_pps_rx.add(stats->ipackets);
}
@@ -1666,14 +1684,15 @@ void CPhyEthIF::get_stats(CPhyEthIFStats *stats){
m_last_tx_rate = m_bw_tx.add(stats->obytes);
m_last_rx_rate = m_bw_rx.add(stats->ibytes);
- m_last_pps = m_pps_tx.add(stats->opackets);
+ m_last_tx_pps = m_pps_tx.add(stats->opackets);
+ m_last_rx_pps = m_pps_rx.add(stats->ipackets);
}
void dump_hw_state(FILE *fd,struct ixgbe_hw_stats *hs ){
- #define DP_A1(f) if (hs->f) fprintf(fd," %-40s : %llu \n",#f,hs->f)
- #define DP_A2(f,m) for (i=0;i<m; i++) { if (hs->f[i]) fprintf(fd," %-40s[%d] : %llu \n",#f,i,hs->f[i]); }
+ #define DP_A1(f) if (hs->f) fprintf(fd," %-40s : %llu \n",#f, (unsigned long long)hs->f)
+ #define DP_A2(f,m) for (i=0;i<m; i++) { if (hs->f[i]) fprintf(fd," %-40s[%d] : %llu \n",#f,i, (unsigned long long)hs->f[i]); }
int i;
//for (i=0;i<8; i++) { if (hs->mpc[i]) fprintf(fd," %-40s[%d] : %llu \n","mpc",i,hs->mpc[i]); }
@@ -1855,6 +1874,9 @@ public:
bool process_rx_pkt(pkt_dir_t dir,rte_mbuf_t * m);
+ virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, rte_mbuf_t *m);
+
+ virtual pkt_dir_t port_id_to_dir(uint8_t port_id);
public:
void GetCoreCounters(CVirtualIFPerSideStats *stats);
@@ -1867,7 +1889,11 @@ public:
return ( CGlobalInfo::m_socket.port_to_socket( m_ports[0].m_port->get_port_id() ) );
}
-private:
+ const CCorePerPort * get_ports() {
+ return m_ports;
+ }
+
+protected:
int send_burst(CCorePerPort * lp_port,
uint16_t len,
@@ -1878,11 +1904,17 @@ private:
-private:
+protected:
uint8_t m_core_id;
uint16_t m_mbuf_cache;
CCorePerPort m_ports[CS_NUM]; /* each core has 2 tx queues 1. client side and server side */
CNodeRing * m_ring_to_rx;
+
+} __rte_cache_aligned; ;
+
+class CCoreEthIFStateless : public CCoreEthIF {
+public:
+ virtual int send_node(CGenNode * node);
};
bool CCoreEthIF::Create(uint8_t core_id,
@@ -1904,54 +1936,6 @@ bool CCoreEthIF::Create(uint8_t core_id,
return (true);
}
-bool CCoreEthIF::process_rx_pkt(pkt_dir_t dir,
- rte_mbuf_t * m){
-
- CSimplePacketParser parser(m);
- if ( !parser.Parse() ){
- return false;
- }
- bool send=false;
- if ( parser.IsLatencyPkt() ){
- send=true;
-
- }else{
- if ( get_is_rx_filter_enable() ){
- uint8_t max_ttl = 0xff - get_rx_check_hops();
- uint8_t pkt_ttl = parser.getTTl();
- if ( (pkt_ttl==max_ttl) || (pkt_ttl==(max_ttl-1) ) ) {
- send=true;
- }
- }
- }
-
-
- if (send) {
- CGenNodeLatencyPktInfo * node=(CGenNodeLatencyPktInfo * )CGlobalInfo::create_node();
- if ( node ) {
- node->m_msg_type = CGenNodeMsgBase::LATENCY_PKT;
- node->m_dir = dir;
- node->m_latency_offset = 0xdead;
- node->m_pkt = m;
- if ( m_ring_to_rx->Enqueue((CGenNode*)node)==0 ){
- }else{
- CGlobalInfo::free_node((CGenNode *)node);
- send=false;
- }
-
- #ifdef LATENCY_QUEUE_TRACE_
- printf("rx to cp --\n");
- rte_pktmbuf_dump(stdout,m, rte_pktmbuf_pkt_len(m));
- #endif
- }else{
- send=false;
- }
- }
- return (send);
-}
-
-
-
void CCoreEthIF::flush_rx_queue(void){
pkt_dir_t dir ;
bool is_latency=get_is_latency_thread_enable();
@@ -2004,7 +1988,6 @@ int CCoreEthIF::flush_tx_queue(void){
return (0);
}
-
void CCoreEthIF::GetCoreCounters(CVirtualIFPerSideStats *stats){
stats->Clear();
pkt_dir_t dir ;
@@ -2084,6 +2067,8 @@ int CCoreEthIF::send_burst(CCorePerPort * lp_port,
rte_pktmbuf_free(m);
}
}
+
+ return (0);
}
@@ -2104,6 +2089,8 @@ int CCoreEthIF::send_pkt(CCorePerPort * lp_port,
len = 0;
}
lp_port->m_len = len;
+
+ return (0);
}
@@ -2140,6 +2127,23 @@ void CCoreEthIF::update_mac_addr(CGenNode * node,uint8_t *p){
}
+
+int CCoreEthIFStateless::send_node(CGenNode * no){
+ CGenNodeStateless * node_sl=(CGenNodeStateless *) no;
+
+ /* check that we have mbuf */
+ rte_mbuf_t * m=node_sl->get_cache_mbuf();
+ assert( m );
+ pkt_dir_t dir=(pkt_dir_t)node_sl->get_mbuf_cache_dir();
+ CCorePerPort * lp_port=&m_ports[dir];
+ CVirtualIFPerSideStats * lp_stats = &m_stats[dir];
+ rte_pktmbuf_refcnt_update(m,1);
+ send_pkt(lp_port,m,lp_stats);
+ return (0);
+};
+
+
+
int CCoreEthIF::send_node(CGenNode * node){
if ( unlikely( node->get_cache_mbuf() !=NULL ) ) {
@@ -2233,6 +2237,29 @@ int CCoreEthIF::send_node(CGenNode * node){
}
+int CCoreEthIF::update_mac_addr_from_global_cfg(pkt_dir_t dir,
+ rte_mbuf_t *m){
+ assert(m);
+ assert(dir<2);
+ CCorePerPort * lp_port=&m_ports[dir];
+ uint8_t *p=rte_pktmbuf_mtod(m, uint8_t*);
+ uint8_t p_id=lp_port->m_port->get_port_id();
+
+ memcpy(p,CGlobalInfo::m_options.get_dst_src_mac_addr(p_id),12);
+ return (0);
+}
+
+pkt_dir_t
+CCoreEthIF::port_id_to_dir(uint8_t port_id) {
+
+ for (pkt_dir_t dir = 0; dir < CS_NUM; dir++) {
+ if (m_ports[dir].m_port->get_port_id() == port_id) {
+ return dir;
+ }
+ }
+
+ return (CS_INVALID);
+}
class CLatencyHWPort : public CPortLatencyHWBase {
public:
@@ -2344,71 +2371,6 @@ private:
};
-class CZMqPublisher {
-public:
- CZMqPublisher(){
- m_context=0;
- m_publisher=0;
- }
-
- bool Create(uint16_t port,bool disable);
- void Delete();
- void publish_json(std::string & s);
-private:
- void show_zmq_last_error(char *s);
-private:
- void * m_context;
- void * m_publisher;
-};
-
-void CZMqPublisher::show_zmq_last_error(char *s){
- printf(" ERROR %s \n",s);
- printf(" ZMQ: %s",zmq_strerror (zmq_errno ()));
- exit(-1);
-}
-
-
-bool CZMqPublisher::Create(uint16_t port,bool disable){
-
- if (disable) {
- return(true);
- }
- m_context = zmq_ctx_new ();
- if ( m_context == 0 ) {
- show_zmq_last_error((char *)"can't connect to ZMQ library");
- }
- m_publisher = zmq_socket (m_context, ZMQ_PUB);
- if ( m_context == 0 ) {
- show_zmq_last_error((char *)"can't create ZMQ socket");
- }
- char buffer[100];
- sprintf(buffer,"tcp://*:%d",port);
- int rc=zmq_bind (m_publisher, buffer);
- if (rc != 0 ) {
- sprintf(buffer,"can't bind to ZMQ socket %d",port);
- show_zmq_last_error(buffer);
- }
- printf("zmq publisher at: %s \n",buffer);
- return (true);
-}
-
-
-void CZMqPublisher::Delete(){
- if (m_publisher) {
- zmq_close (m_publisher);
- }
- if (m_context) {
- zmq_ctx_destroy (m_context);
- }
-}
-
-
-void CZMqPublisher::publish_json(std::string & s){
- if ( m_publisher ){
- int size = zmq_send (m_publisher, s.c_str(), s.length(), 0);
- assert(size==s.length());
- }
-}
class CPerPortStats {
public:
@@ -2420,6 +2382,10 @@ public:
uint64_t oerrors;
float m_total_tx_bps;
+ float m_total_tx_pps;
+
+ float m_total_rx_bps;
+ float m_total_rx_pps;
};
class CGlobalStats {
@@ -2456,6 +2422,7 @@ public:
float m_tx_bps;
float m_rx_bps;
float m_tx_pps;
+ float m_rx_pps;
float m_tx_cps;
float m_tx_expected_cps;
float m_tx_expected_pps;
@@ -2488,7 +2455,7 @@ std::string CGlobalStats::get_field(std::string name,float &f){
std::string CGlobalStats::get_field(std::string name,uint64_t &f){
char buff[200];
- sprintf(buff,"\"%s\":%llu,",name.c_str(),f);
+ sprintf(buff,"\"%s\":%llu,",name.c_str(), (unsigned long long)f);
return (std::string(buff));
}
@@ -2500,7 +2467,7 @@ std::string CGlobalStats::get_field_port(int port,std::string name,float &f){
std::string CGlobalStats::get_field_port(int port,std::string name,uint64_t &f){
char buff[200];
- sprintf(buff,"\"%s-%d\":%llu,",name.c_str(),port,f);
+ sprintf(buff,"\"%s-%d\":%llu,",name.c_str(),port, (unsigned long long)f);
return (std::string(buff));
}
@@ -2516,6 +2483,7 @@ void CGlobalStats::dump_json(std::string & json){
json+=GET_FIELD(m_tx_bps);
json+=GET_FIELD(m_rx_bps);
json+=GET_FIELD(m_tx_pps);
+ json+=GET_FIELD(m_rx_pps);
json+=GET_FIELD(m_tx_cps);
json+=GET_FIELD(m_tx_expected_cps);
json+=GET_FIELD(m_tx_expected_pps);
@@ -2550,6 +2518,9 @@ void CGlobalStats::dump_json(std::string & json){
json+=GET_FIELD_PORT(i,ierrors) ;
json+=GET_FIELD_PORT(i,oerrors) ;
json+=GET_FIELD_PORT(i,m_total_tx_bps);
+ json+=GET_FIELD_PORT(i,m_total_tx_pps);
+ json+=GET_FIELD_PORT(i,m_total_rx_bps);
+ json+=GET_FIELD_PORT(i,m_total_rx_pps);
}
json+=m_template.dump_as_json("template");
json+="\"unknown\":0}}" ;
@@ -2569,7 +2540,7 @@ void CGlobalStats::DumpAllPorts(FILE *fd){
fprintf (fd," Platform_factor : %2.1f \n",m_platform_factor);
fprintf (fd," Total-Tx : %s ",double_to_human_str(m_tx_bps,"bps",KBYE_1000).c_str());
if ( CGlobalInfo::is_learn_mode() ) {
- fprintf (fd," Nat_time_out : %8llu \n",m_total_nat_time_out);
+ fprintf (fd," Nat_time_out : %8llu \n", (unsigned long long)m_total_nat_time_out);
}else{
fprintf (fd,"\n");
}
@@ -2577,49 +2548,52 @@ void CGlobalStats::DumpAllPorts(FILE *fd){
fprintf (fd," Total-Rx : %s ",double_to_human_str(m_rx_bps,"bps",KBYE_1000).c_str());
if ( CGlobalInfo::is_learn_mode() ) {
- fprintf (fd," Nat_no_fid : %8llu \n",m_total_nat_no_fid);
+ fprintf (fd," Nat_no_fid : %8llu \n", (unsigned long long)m_total_nat_no_fid);
}else{
fprintf (fd,"\n");
}
fprintf (fd," Total-PPS : %s ",double_to_human_str(m_tx_pps,"pps",KBYE_1000).c_str());
if ( CGlobalInfo::is_learn_mode() ) {
- fprintf (fd," Total_nat_active: %8llu \n",m_total_nat_active);
+ fprintf (fd," Total_nat_active: %8llu \n", (unsigned long long)m_total_nat_active);
}else{
fprintf (fd,"\n");
}
fprintf (fd," Total-CPS : %s ",double_to_human_str(m_tx_cps,"cps",KBYE_1000).c_str());
if ( CGlobalInfo::is_learn_mode() ) {
- fprintf (fd," Total_nat_open : %8llu \n",m_total_nat_open);
+ fprintf (fd," Total_nat_open : %8llu \n", (unsigned long long)m_total_nat_open);
}else{
fprintf (fd,"\n");
}
fprintf (fd,"\n");
fprintf (fd," Expected-PPS : %s ",double_to_human_str(m_tx_expected_pps,"pps",KBYE_1000).c_str());
if ( CGlobalInfo::is_learn_verify_mode() ) {
- fprintf (fd," Nat_learn_errors: %8llu \n",m_total_nat_learn_error);
+ fprintf (fd," Nat_learn_errors: %8llu \n", (unsigned long long)m_total_nat_learn_error);
}else{
fprintf (fd,"\n");
}
fprintf (fd," Expected-CPS : %s \n",double_to_human_str(m_tx_expected_cps,"cps",KBYE_1000).c_str());
fprintf (fd," Expected-BPS : %s \n",double_to_human_str(m_tx_expected_bps,"bps",KBYE_1000).c_str());
fprintf (fd,"\n");
- fprintf (fd," Active-flows : %8llu Clients : %8llu Socket-util : %3.4f %% \n",(uint64_t)m_active_flows,m_total_clients,m_socket_util);
+ fprintf (fd," Active-flows : %8llu Clients : %8llu Socket-util : %3.4f %% \n",
+ (unsigned long long)m_active_flows,
+ (unsigned long long)m_total_clients,
+ m_socket_util);
fprintf (fd," Open-flows : %8llu Servers : %8llu Socket : %8llu Socket/Clients : %.1f \n",
- (uint64_t)m_open_flows,
- m_total_servers,
- m_active_sockets,
+ (unsigned long long)m_open_flows,
+ (unsigned long long)m_total_servers,
+ (unsigned long long)m_active_sockets,
(float)m_active_sockets/(float)m_total_clients);
if (m_total_alloc_error) {
- fprintf (fd," Total_alloc_err : %llu \n",(uint64_t)m_total_alloc_error);
+ fprintf (fd," Total_alloc_err : %llu \n", (unsigned long long)m_total_alloc_error);
}
if ( m_total_queue_full ){
- fprintf (fd," Total_queue_full : %llu \n",(uint64_t)m_total_queue_full);
+ fprintf (fd," Total_queue_full : %llu \n", (unsigned long long)m_total_queue_full);
}
if (m_total_queue_drop) {
- fprintf (fd," Total_queue_drop : %llu \n",(uint64_t)m_total_queue_drop);
+ fprintf (fd," Total_queue_drop : %llu \n", (unsigned long long)m_total_queue_drop);
}
//m_template.Dump(fd);
@@ -2643,8 +2617,8 @@ void CGlobalStats::Dump(FILE *fd,DumpFormat mode){
CPerPortStats * lp=&m_port[i];
fprintf(fd,"port : %d \n",(int)i);
fprintf(fd,"------------\n");
- #define GS_DP_A4(f) fprintf(fd," %-40s : %llu \n",#f,lp->f)
- #define GS_DP_A(f) if (lp->f) fprintf(fd," %-40s : %llu \n",#f,lp->f)
+ #define GS_DP_A4(f) fprintf(fd," %-40s : %llu \n",#f, (unsigned long long)lp->f)
+ #define GS_DP_A(f) if (lp->f) fprintf(fd," %-40s : %llu \n",#f, (unsigned long long)lp->f)
GS_DP_A4(opackets);
GS_DP_A4(obytes);
GS_DP_A4(ipackets);
@@ -2719,10 +2693,10 @@ void CGlobalStats::Dump(FILE *fd,DumpFormat mode){
-struct CGlobalPortCfg {
+struct CGlobalTRex {
public:
- CGlobalPortCfg (){
+ CGlobalTRex (){
m_max_ports=4;
m_max_cores=1;
m_cores_to_dual_ports=0;
@@ -2732,10 +2706,11 @@ public:
m_expected_pps=0.0;
m_expected_cps=0.0;
m_expected_bps=0.0;
+ m_trex_stateless = NULL;
}
public:
- bool Create(bool is_stateless);
+ bool Create();
void Delete();
int ixgbe_prob_init();
@@ -2751,9 +2726,22 @@ public:
int reset_counters();
+public:
+
+private:
+ /* try to stop all datapath cores */
+ void try_stop_all_dp();
+ /* send message to all dp cores */
+ int send_message_all_dp(TrexStatelessCpToDpMsgBase *msg);
+
+ void check_for_dp_message_from_core(int thread_id);
+ void check_for_dp_messages();
public:
+
int start_send_master();
+ int start_master_stateless();
+
int run_in_core(virtual_thread_id_t virt_core_id);
int stop_core(virtual_thread_id_t virt_core_id);
@@ -2800,7 +2788,6 @@ public:
- int test_send1();
int rcv_send(int port,int queue_id);
int rcv_send_all(int queue_id);
@@ -2814,7 +2801,7 @@ private:
int create_pkt(uint8_t *pkt,int pkt_size);
int create_udp_pkt();
- int create_sctp_pkt();
+ int create_icmp_pkt();
@@ -2866,7 +2853,9 @@ public:
CPhyEthIF m_ports[BP_MAX_PORTS];
- CCoreEthIF m_cores_vif[BP_MAX_CORES]; /* counted from 1 , 2,3 core zero is reserve*/
+ CCoreEthIF m_cores_vif_sf[BP_MAX_CORES]; /* counted from 1 , 2,3 core zero is reserve - stateful */
+ CCoreEthIFStateless m_cores_vif_sl[BP_MAX_CORES]; /* counted from 1 , 2,3 core zero is reserve - stateless*/
+ CCoreEthIF * m_cores_vif[BP_MAX_CORES];
CParserOption m_po ;
@@ -2888,55 +2877,15 @@ private:
CLatencyVmPort m_latency_vm_vports[BP_MAX_PORTS]; /* vm driver */
CLatencyPktInfo m_latency_pkt;
- CZMqPublisher m_zmq_publisher;
-};
-
-
-
-int CGlobalPortCfg::test_send1(){
+ TrexPublisher m_zmq_publisher;
- CParserOption po ;
- CFlowGenList fl;
-
- po.cfg_file = "cap2/dns.yaml";
- //po.cfg_file = "cap2/sfr3.yaml";
- //po.cfg_file = "cap2/sfr4.yaml";
- //po.cfg_file = "cap2/sfr.yaml";
-
- po.preview.setVMode(3);
- po.preview.setFileWrite(true);
-
- fl.Create();
-
- fl.load_from_yaml(po.cfg_file,1);
- //fl.DumpPktSize();
-
- fl.generate_p_thread_info(1);
- CFlowGenListPerThread * lpt;
-
- int i;
- for (i=0; i<1; i++) {
- lpt = fl.m_threads_info[i];
- //CNullIF * erf_vif = new CNullIF();
- CVirtualIF * erf_vif = &m_cores_vif[0];
- lpt->set_vif(erf_vif);
- lpt->generate_erf("hey",po.preview);
- lpt->m_node_gen.DumpHist(stdout);
- lpt->DumpStats(stdout);
- }
-
- m_cores_vif[0].flush_tx_queue();
- delay(1000);
- //fprintf(stdout," drop : %llu \n",m_test_drop);
-
- m_cores_vif[0].DumpCoreStats(stdout);
- m_cores_vif[0].DumpIfStats(stdout);
+public:
+ TrexStateless *m_trex_stateless;
+};
- fl.Delete();
-}
-int CGlobalPortCfg::rcv_send(int port,int queue_id){
+int CGlobalTRex::rcv_send(int port,int queue_id){
CPhyEthIF * lp=&m_ports[port];
rte_mbuf_t * rx_pkts[32];
@@ -2955,7 +2904,7 @@ int CGlobalPortCfg::rcv_send(int port,int queue_id){
return (0);
}
-int CGlobalPortCfg::rcv_send_all(int queue_id){
+int CGlobalTRex::rcv_send_all(int queue_id){
int i;
for (i=0; i<m_max_ports; i++) {
rcv_send(i,queue_id);
@@ -2966,16 +2915,15 @@ int CGlobalPortCfg::rcv_send_all(int queue_id){
-int CGlobalPortCfg::test_send(){
+int CGlobalTRex::test_send(){
int i;
- CPhyEthIF * lp=&m_ports[0];
-
//set_promisc_all(true);
- //create_sctp_pkt();
create_udp_pkt();
CRx_check_header rx_check_header;
+ (void)rx_check_header;
+
rx_check_header.m_time_stamp=0x1234567;
rx_check_header.m_option_type=RX_CHECK_V4_OPT_TYPE;
rx_check_header.m_option_len=RX_CHECK_V4_OPT_LEN;
@@ -2993,18 +2941,7 @@ int CGlobalPortCfg::test_send(){
//test_send_pkts(m_latency_tx_queue_id,1,2);
//test_send_pkts(m_latency_tx_queue_id,1,3);
test_send_pkts(0,1,0);
- test_send_pkts(0,1,1);
- //test_send_pkts(2,1,0);
-
-
- //test_send_pkts(0,1,1);
- //test_send_pkts(0,1,2);
- //test_send_pkts(0,1,3);
-
- /*test_send_pkts(2,1,0);
- test_send_pkts(2,1,1);
- test_send_pkts(2,1,2);
- test_send_pkts(2,1,3);*/
+ test_send_pkts(0,2,1);
/*delay(1000);
fprintf(stdout," --------------------------------\n");
@@ -3049,7 +2986,7 @@ int CGlobalPortCfg::test_send(){
}*/
#endif
- fprintf(stdout," drop : %llu \n",m_test_drop);
+ fprintf(stdout," drop : %llu \n", (unsigned long long)m_test_drop);
return (0);
}
@@ -3089,22 +3026,21 @@ const uint8_t udp_pkt[]={
};
-const uint8_t sctp_pkt1[]={
-
+const uint8_t icmp_pkt1[]={
0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x00,0x00,0x01,0x00,0x00,
0x08,0x00,
0x45,0x02,0x00,0x30,
0x00,0x00,0x40,0x00,
- 0x40,0x84,0xbd,0x04,
- 0x01,0x01,0x01,0x01, //sIP
- 0x02,0x02,0x02,0x02, //DIP
+ 0xaa,0x01,0xbd,0x04,
+ 0x9b,0xe6,0x18,0x9b, //SIP
+ 0xcb,0xff,0xfc,0xc2, //DIP
- 0x80,0x44,//SPORT
- 0x00,0x50,//DPORT
-
- 0x00,0x00,0x00,0x00, //checksum
+ 0x08, 0x00,
+ 0x01, 0x02, //checksum
+ 0xaa, 0xbb, // id
+ 0x00, 0x00, // Sequence number
0x11,0x22,0x33,0x44, // magic
0x00,0x00,0x00,0x00, //64 bit counter
@@ -3112,13 +3048,12 @@ const uint8_t sctp_pkt1[]={
0x00,0x01,0xa0,0x00, //seq
0x00,0x00,0x00,0x00,
-};
+};
-
-int CGlobalPortCfg::create_pkt(uint8_t *pkt,int pkt_size){
+int CGlobalTRex::create_pkt(uint8_t *pkt,int pkt_size){
rte_mempool_t * mp= CGlobalInfo::m_mem_pool[0].m_big_mbuf_pool ;
rte_mbuf_t * m=rte_pktmbuf_alloc(mp);
@@ -3138,17 +3073,17 @@ int CGlobalPortCfg::create_pkt(uint8_t *pkt,int pkt_size){
return (0);
}
-int CGlobalPortCfg::create_udp_pkt(){
+int CGlobalTRex::create_udp_pkt(){
return (create_pkt((uint8_t*)udp_pkt,sizeof(udp_pkt)));
}
-int CGlobalPortCfg::create_sctp_pkt(){
- return (create_pkt((uint8_t*)sctp_pkt1,sizeof(sctp_pkt1)));
+int CGlobalTRex::create_icmp_pkt(){
+ return (create_pkt((uint8_t*)icmp_pkt1,sizeof(icmp_pkt1)));
}
/* test by sending 10 packets ...*/
-int CGlobalPortCfg::test_send_pkts(uint16_t queue_id,
+int CGlobalTRex::test_send_pkts(uint16_t queue_id,
int pkt,
int port){
@@ -3174,26 +3109,72 @@ int CGlobalPortCfg::test_send_pkts(uint16_t queue_id,
-int CGlobalPortCfg::set_promisc_all(bool enable){
+int CGlobalTRex::set_promisc_all(bool enable){
int i;
for (i=0; i<m_max_ports; i++) {
CPhyEthIF * _if=&m_ports[i];
_if->set_promiscuous(enable);
}
+
+ return (0);
}
-int CGlobalPortCfg::reset_counters(){
+int CGlobalTRex::reset_counters(){
int i;
for (i=0; i<m_max_ports; i++) {
CPhyEthIF * _if=&m_ports[i];
_if->stats_clear();
}
+
+ return (0);
+}
+
+/**
+ * check for a single core
+ *
+ * @author imarom (19-Nov-15)
+ *
+ * @param thread_id
+ */
+void
+CGlobalTRex::check_for_dp_message_from_core(int thread_id) {
+
+ CNodeRing *ring = CMsgIns::Ins()->getCpDp()->getRingDpToCp(thread_id);
+
+ /* fast path check */
+ if ( likely ( ring->isEmpty() ) ) {
+ return;
+ }
+
+ while ( true ) {
+ CGenNode * node = NULL;
+ if (ring->Dequeue(node) != 0) {
+ break;
+ }
+ assert(node);
+
+ TrexStatelessDpToCpMsgBase * msg = (TrexStatelessDpToCpMsgBase *)node;
+ msg->handle();
+ delete msg;
+ }
+
}
+/**
+ * check for messages that arrived from DP to CP
+ *
+ */
+void
+CGlobalTRex::check_for_dp_messages() {
+ /* for all the cores - check for a new message */
+ for (int i = 0; i < get_cores_tx(); i++) {
+ check_for_dp_message_from_core(i);
+ }
+}
-bool CGlobalPortCfg::is_all_links_are_up(bool dump){
+bool CGlobalTRex::is_all_links_are_up(bool dump){
bool all_link_are=true;
int i;
for (i=0; i<m_max_ports; i++) {
@@ -3211,8 +3192,43 @@ bool CGlobalPortCfg::is_all_links_are_up(bool dump){
}
+void CGlobalTRex::try_stop_all_dp(){
+
+ TrexStatelessDpQuit * msg= new TrexStatelessDpQuit();
+ send_message_all_dp(msg);
+ delete msg;
+ bool all_core_finished = false;
+ int i;
+ for (i=0; i<20; i++) {
+ if ( is_all_cores_finished() ){
+ all_core_finished =true;
+ break;
+ }
+ delay(100);
+ }
+ if ( all_core_finished ){
+ m_zmq_publisher.publish_event(TrexPublisher::EVENT_SERVER_STOPPED);
+ printf(" All cores stopped !! \n");
+ }else{
+ printf(" ERROR one of the DP core is stucked !\n");
+ }
+}
+
+
+int CGlobalTRex::send_message_all_dp(TrexStatelessCpToDpMsgBase *msg){
+
+ int max_threads=(int)CMsgIns::Ins()->getCpDp()->get_num_threads();
+ int i;
+
+ for (i=0; i<max_threads; i++) {
+ CNodeRing *ring = CMsgIns::Ins()->getCpDp()->getRingCpToDp((uint8_t)i);
+ ring->Enqueue((CGenNode*)msg->clone());
+ }
+ return (0);
+}
+
-int CGlobalPortCfg::ixgbe_rx_queue_flush(){
+int CGlobalTRex::ixgbe_rx_queue_flush(){
int i;
for (i=0; i<m_max_ports; i++) {
CPhyEthIF * _if=&m_ports[i];
@@ -3222,7 +3238,7 @@ int CGlobalPortCfg::ixgbe_rx_queue_flush(){
}
-int CGlobalPortCfg::ixgbe_configure_mg(void){
+int CGlobalTRex::ixgbe_configure_mg(void){
int i;
CLatencyManagerCfg mg_cfg;
mg_cfg.m_max_ports = m_max_ports;
@@ -3262,10 +3278,12 @@ int CGlobalPortCfg::ixgbe_configure_mg(void){
m_mg.Create(&mg_cfg);
m_mg.set_mask(CGlobalInfo::m_options.m_latency_mask);
+
+ return (0);
}
-int CGlobalPortCfg::ixgbe_start(void){
+int CGlobalTRex::ixgbe_start(void){
int i;
for (i=0; i<m_max_ports; i++) {
@@ -3307,7 +3325,7 @@ int CGlobalPortCfg::ixgbe_start(void){
m_cores_to_dual_ports+1,
&m_port_cfg.m_port_conf);
- /* the latency queue for SCTP */
+ /* the latency queue for latency measurement packets */
m_latency_tx_queue_id= m_cores_to_dual_ports;
socket_id_t socket_id = CGlobalInfo::m_socket.port_to_socket((port_id_t)i);
@@ -3324,7 +3342,7 @@ int CGlobalPortCfg::ixgbe_start(void){
/* set the filter queue */
_if->set_rx_queue(1);
- /* sctp ring is 1 */
+ /* latency measurement ring is 1 */
_if->rx_queue_setup(1,
RTE_TEST_RX_LATENCY_DESC_DEFAULT,
socket_id,
@@ -3384,11 +3402,15 @@ int CGlobalPortCfg::ixgbe_start(void){
*/
int port_offset=0;
- int queue_offset=0;
for (i=0; i<get_cores_tx(); i++) {
int j=(i+1);
int queue_id=((j-1)/get_base_num_cores() ); /* for the first min core queue 0 , then queue 1 etc */
- m_cores_vif[j].Create(j,
+ if ( get_is_stateless() ){
+ m_cores_vif[j]=&m_cores_vif_sl[j];
+ }else{
+ m_cores_vif[j]=&m_cores_vif_sf[j];
+ }
+ m_cores_vif[j]->Create(j,
queue_id,
&m_ports[port_offset], /* 0,2*/
queue_id,
@@ -3403,28 +3425,25 @@ int CGlobalPortCfg::ixgbe_start(void){
fprintf(stdout," -------------------------------\n");
CCoreEthIF::DumpIfCfgHeader(stdout);
for (i=0; i<get_cores_tx(); i++) {
- m_cores_vif[i+1].DumpIfCfg(stdout);
+ m_cores_vif[i+1]->DumpIfCfg(stdout);
}
fprintf(stdout," -------------------------------\n");
+
+ return (0);
}
-bool CGlobalPortCfg::Create(bool is_stateless){
+bool CGlobalTRex::Create(){
+ CFlowsYamlInfo pre_yaml_info;
- /* hack - need to refactor */
- if (!is_stateless) {
- if ( !m_zmq_publisher.Create( CGlobalInfo::m_options.m_zmq_port,
- !CGlobalInfo::m_options.preview.get_zmq_publish_enable() ) ){
- return (false);
- }
+ if (!get_is_stateless()) {
+ pre_yaml_info.load_from_yaml_file(CGlobalInfo::m_options.cfg_file);
}
- /* We load the YAML twice,
- this is the first time. to update global flags */
- CFlowsYamlInfo pre_yaml_info;
- if (!is_stateless) {
- pre_yaml_info.load_from_yaml_file(CGlobalInfo::m_options.cfg_file);
- }
+ if ( !m_zmq_publisher.Create( CGlobalInfo::m_options.m_zmq_port,
+ !CGlobalInfo::m_options.preview.get_zmq_publish_enable() ) ){
+ return (false);
+ }
if ( pre_yaml_info.m_vlan_info.m_enable ){
CGlobalInfo::m_options.preview.set_vlan_mode_enable(true);
@@ -3434,16 +3453,17 @@ bool CGlobalPortCfg::Create(bool is_stateless){
ixgbe_prob_init();
cores_prob_init();
queues_prob_init();
- /* allocate rings */
- assert( CMsgIns::Ins()->Create(get_cores_tx()) );
- if ( sizeof(CGenNodeNatInfo) != sizeof(CGenNode) ) {
- printf("ERROR sizeof(CGenNodeNatInfo) %d != sizeof(CGenNode) %d must be the same size \n",sizeof(CGenNodeNatInfo),sizeof(CGenNode));
- assert(0);
- }
+ /* allocate rings */
+ assert( CMsgIns::Ins()->Create(get_cores_tx()) );
+
+ if ( sizeof(CGenNodeNatInfo) != sizeof(CGenNode) ) {
+ printf("ERROR sizeof(CGenNodeNatInfo) %lu != sizeof(CGenNode) %lu must be the same size \n",sizeof(CGenNodeNatInfo),sizeof(CGenNode));
+ assert(0);
+ }
if ( sizeof(CGenNodeLatencyPktInfo) != sizeof(CGenNode) ) {
- printf("ERROR sizeof(CGenNodeLatencyPktInfo) %d != sizeof(CGenNode) %d must be the same size \n",sizeof(CGenNodeLatencyPktInfo),sizeof(CGenNode));
+ printf("ERROR sizeof(CGenNodeLatencyPktInfo) %lu != sizeof(CGenNode) %lu must be the same size \n",sizeof(CGenNodeLatencyPktInfo),sizeof(CGenNode));
assert(0);
}
@@ -3460,19 +3480,34 @@ bool CGlobalPortCfg::Create(bool is_stateless){
CGlobalInfo::init_pools(rx_mbuf);
ixgbe_start();
dump_config(stdout);
+
+ /* start stateless */
+ if (get_is_stateless()) {
+
+ TrexStatelessCfg cfg;
+
+ TrexRpcServerConfig rpc_req_resp_cfg(TrexRpcServerConfig::RPC_PROT_TCP, global_platform_cfg_info.m_zmq_rpc_port);
+
+ cfg.m_port_count = CGlobalInfo::m_options.m_expected_portd;
+ cfg.m_rpc_req_resp_cfg = &rpc_req_resp_cfg;
+ cfg.m_rpc_async_cfg = NULL;
+ cfg.m_rpc_server_verbose = false;
+ cfg.m_platform_api = new TrexDpdkPlatformApi();
+ cfg.m_publisher = &m_zmq_publisher;
+
+ m_trex_stateless = new TrexStateless(cfg);
+ }
+
return (true);
}
-void CGlobalPortCfg::Delete(){
+void CGlobalTRex::Delete(){
m_zmq_publisher.Delete();
}
-int CGlobalPortCfg::ixgbe_prob_init(void){
-
- uint8_t nb_ports;
-
+int CGlobalTRex::ixgbe_prob_init(void){
m_max_ports = rte_eth_dev_count();
if (m_max_ports == 0)
@@ -3561,13 +3596,13 @@ int CGlobalPortCfg::ixgbe_prob_init(void){
return (0);
}
-int CGlobalPortCfg::cores_prob_init(){
+int CGlobalTRex::cores_prob_init(){
m_max_cores = rte_lcore_count();
assert(m_max_cores>0);
return (0);
}
-int CGlobalPortCfg::queues_prob_init(){
+int CGlobalTRex::queues_prob_init(){
if (m_max_cores < 2) {
rte_exit(EXIT_FAILURE, "number of cores should be at least 3 \n");
@@ -3608,7 +3643,7 @@ int CGlobalPortCfg::queues_prob_init(){
}
-void CGlobalPortCfg::dump_config(FILE *fd){
+void CGlobalTRex::dump_config(FILE *fd){
fprintf(fd," number of ports : %u \n",m_max_ports);
fprintf(fd," max cores for 2 ports : %u \n",m_cores_to_dual_ports);
fprintf(fd," max queue per port : %u \n",m_max_queues_per_port);
@@ -3616,7 +3651,7 @@ void CGlobalPortCfg::dump_config(FILE *fd){
-void CGlobalPortCfg::dump_post_test_stats(FILE *fd){
+void CGlobalTRex::dump_post_test_stats(FILE *fd){
uint64_t pkt_out=0;
uint64_t pkt_out_bytes=0;
uint64_t pkt_in_bytes=0;
@@ -3627,7 +3662,7 @@ void CGlobalPortCfg::dump_post_test_stats(FILE *fd){
int i;
for (i=0; i<get_cores_tx(); i++) {
- CCoreEthIF * erf_vif = &m_cores_vif[i+1];
+ CCoreEthIF * erf_vif = m_cores_vif[i+1];
CVirtualIFPerSideStats stats;
erf_vif->GetCoreCounters(&stats);
sw_pkt_out += stats.m_tx_pkt;
@@ -3652,17 +3687,17 @@ void CGlobalPortCfg::dump_post_test_stats(FILE *fd){
fprintf (fd," summary stats \n");
fprintf (fd," -------------- \n");
- fprintf (fd," Total-pkt-drop : %d pkts \n",(int64_t)(pkt_out-pkt_in));
- fprintf (fd," Total-tx-bytes : %llu bytes \n",pkt_out_bytes);
- fprintf (fd," Total-tx-sw-bytes : %llu bytes \n",sw_pkt_out_bytes);
- fprintf (fd," Total-rx-bytes : %llu byte \n",pkt_in_bytes);
+ fprintf (fd," Total-pkt-drop : %llu pkts \n",(unsigned long long)(pkt_out-pkt_in));
+ fprintf (fd," Total-tx-bytes : %llu bytes \n", (unsigned long long)pkt_out_bytes);
+ fprintf (fd," Total-tx-sw-bytes : %llu bytes \n", (unsigned long long)sw_pkt_out_bytes);
+ fprintf (fd," Total-rx-bytes : %llu byte \n", (unsigned long long)pkt_in_bytes);
fprintf (fd," \n");
- fprintf (fd," Total-tx-pkt : %llu pkts \n",pkt_out);
- fprintf (fd," Total-rx-pkt : %llu pkts \n",pkt_in);
- fprintf (fd," Total-sw-tx-pkt : %llu pkts \n",sw_pkt_out);
- fprintf (fd," Total-sw-err : %llu pkts \n",sw_pkt_out_err);
+ fprintf (fd," Total-tx-pkt : %llu pkts \n", (unsigned long long)pkt_out);
+ fprintf (fd," Total-rx-pkt : %llu pkts \n", (unsigned long long)pkt_in);
+ fprintf (fd," Total-sw-tx-pkt : %llu pkts \n", (unsigned long long)sw_pkt_out);
+ fprintf (fd," Total-sw-err : %llu pkts \n", (unsigned long long)sw_pkt_out_err);
if ( !CGlobalInfo::m_options.is_latency_disabled() ){
@@ -3675,7 +3710,7 @@ void CGlobalPortCfg::dump_post_test_stats(FILE *fd){
}
-void CGlobalPortCfg::update_stats(){
+void CGlobalTRex::update_stats(){
int i;
for (i=0; i<m_max_ports; i++) {
@@ -3696,12 +3731,13 @@ void CGlobalPortCfg::update_stats(){
}
-void CGlobalPortCfg::get_stats(CGlobalStats & stats){
+void CGlobalTRex::get_stats(CGlobalStats & stats){
int i;
float total_tx=0.0;
float total_rx=0.0;
- float total_pps=0.0;
+ float total_tx_pps=0.0;
+ float total_rx_pps=0.0;
stats.m_total_tx_pkts = 0;
stats.m_total_rx_pkts = 0;
@@ -3729,6 +3765,9 @@ void CGlobalPortCfg::get_stats(CGlobalStats & stats){
stp->ierrors = st.ierrors;
stp->oerrors = st.oerrors;
stp->m_total_tx_bps = _if->get_last_tx_rate()*_1Mb_DOUBLE;
+ stp->m_total_tx_pps = _if->get_last_tx_pps_rate();
+ stp->m_total_rx_bps = _if->get_last_rx_rate()*_1Mb_DOUBLE;
+ stp->m_total_rx_pps = _if->get_last_rx_pps_rate();
stats.m_total_tx_pkts += st.opackets;
stats.m_total_rx_pkts += st.ipackets;
@@ -3737,7 +3776,8 @@ void CGlobalPortCfg::get_stats(CGlobalStats & stats){
total_tx +=_if->get_last_tx_rate();
total_rx +=_if->get_last_rx_rate();
- total_pps +=_if->get_last_pps_rate();
+ total_tx_pps +=_if->get_last_tx_pps_rate();
+ total_rx_pps +=_if->get_last_rx_pps_rate();
}
@@ -3798,7 +3838,13 @@ void CGlobalPortCfg::get_stats(CGlobalStats & stats){
stats.m_total_clients = total_clients;
stats.m_total_servers = total_servers;
stats.m_active_sockets = active_sockets;
- stats.m_socket_util =100.0*(double)active_sockets/(double)total_sockets;
+
+ if (total_sockets != 0) {
+ stats.m_socket_util =100.0*(double)active_sockets/(double)total_sockets;
+ } else {
+ stats.m_socket_util = 0;
+ }
+
float drop_rate=total_tx-total_rx;
@@ -3814,7 +3860,8 @@ void CGlobalPortCfg::get_stats(CGlobalStats & stats){
stats.m_tx_bps = total_tx*pf*_1Mb_DOUBLE;
stats.m_rx_bps = total_rx*pf*_1Mb_DOUBLE;
- stats.m_tx_pps = total_pps*pf;
+ stats.m_tx_pps = total_tx_pps*pf;
+ stats.m_rx_pps = total_rx_pps*pf;
stats.m_tx_cps = m_last_total_cps*pf;
stats.m_tx_expected_cps = m_expected_cps*pf;
@@ -3822,7 +3869,7 @@ void CGlobalPortCfg::get_stats(CGlobalStats & stats){
stats.m_tx_expected_bps = m_expected_bps*pf;
}
-bool CGlobalPortCfg::sanity_check(){
+bool CGlobalTRex::sanity_check(){
CFlowGenListPerThread * lpt;
uint32_t errors=0;
@@ -3842,7 +3889,7 @@ bool CGlobalPortCfg::sanity_check(){
/* dump the template info */
-void CGlobalPortCfg::dump_template_info(std::string & json){
+void CGlobalTRex::dump_template_info(std::string & json){
CFlowGenListPerThread * lpt = m_fl.m_threads_info[0];
CFlowsYamlInfo * yaml_info=&lpt->m_yaml_info;
@@ -3857,7 +3904,7 @@ void CGlobalPortCfg::dump_template_info(std::string & json){
json+="]}" ;
}
-void CGlobalPortCfg::dump_stats(FILE *fd,std::string & json,
+void CGlobalTRex::dump_stats(FILE *fd,std::string & json,
CGlobalStats::DumpFormat format){
CGlobalStats stats;
update_stats();
@@ -3897,11 +3944,15 @@ void CGlobalPortCfg::dump_stats(FILE *fd,std::string & json,
}
-int CGlobalPortCfg::run_in_master(){
+int CGlobalTRex::run_in_master(){
std::string json;
bool was_stopped=false;
+ if ( get_is_stateless() ) {
+ m_trex_stateless->launch_control_plane();
+ }
+
while ( true ) {
if ( CGlobalInfo::m_options.preview.get_no_keyboard() ==false ){
@@ -3953,10 +4004,10 @@ int CGlobalPortCfg::run_in_master(){
m_fl.m_threads_info[0]->m_node_gen.dump_json(json);
m_zmq_publisher.publish_json(json);
- dump_template_info(json);
- m_zmq_publisher.publish_json(json);
-
-
+ if ( !get_is_stateless() ){
+ dump_template_info(json);
+ m_zmq_publisher.publish_json(json);
+ }
if ( !CGlobalInfo::m_options.is_latency_disabled() ){
m_mg.update();
@@ -4009,6 +4060,13 @@ int CGlobalPortCfg::run_in_master(){
}
+ /* stateless info */
+ m_trex_stateless->generate_publish_snapshot(json);
+ m_zmq_publisher.publish_json(json);
+
+ /* check from messages from DP */
+ check_for_dp_messages();
+
delay(500);
if ( is_all_cores_finished() ) {
@@ -4016,6 +4074,11 @@ int CGlobalPortCfg::run_in_master(){
}
}
+ if (!is_all_cores_finished()) {
+ /* probably CLTR-C */
+ try_stop_all_dp();
+ }
+
m_mg.stop();
delay(1000);
if ( was_stopped ){
@@ -4027,7 +4090,7 @@ int CGlobalPortCfg::run_in_master(){
-int CGlobalPortCfg::run_in_laterncy_core(void){
+int CGlobalTRex::run_in_laterncy_core(void){
if ( !CGlobalInfo::m_options.is_latency_disabled() ){
m_mg.start(0);
}
@@ -4035,12 +4098,12 @@ int CGlobalPortCfg::run_in_laterncy_core(void){
}
-int CGlobalPortCfg::stop_core(virtual_thread_id_t virt_core_id){
+int CGlobalTRex::stop_core(virtual_thread_id_t virt_core_id){
m_signal[virt_core_id]=1;
return (0);
}
-int CGlobalPortCfg::run_in_core(virtual_thread_id_t virt_core_id){
+int CGlobalTRex::run_in_core(virtual_thread_id_t virt_core_id){
CPreviewMode *lp=&CGlobalInfo::m_options.preview;
if ( lp->getSingleCore() &&
@@ -4051,19 +4114,23 @@ int CGlobalPortCfg::run_in_core(virtual_thread_id_t virt_core_id){
return (0);
}
+
assert(m_fl_was_init);
CFlowGenListPerThread * lpt;
lpt = m_fl.m_threads_info[virt_core_id-1];
- lpt->generate_erf(CGlobalInfo::m_options.out_file,*lp);
- //lpt->m_node_gen.DumpHist(stdout);
- //lpt->DumpStats(stdout);
+
+ if (get_is_stateless()) {
+ lpt->start_stateless_daemon(*lp);
+ }else{
+ lpt->start_generate_stateful(CGlobalInfo::m_options.out_file,*lp);
+ }
m_signal[virt_core_id]=1;
return (0);
}
-int CGlobalPortCfg::stop_master(){
+int CGlobalTRex::stop_master(){
delay(1000);
std::string json;
@@ -4084,7 +4151,7 @@ int CGlobalPortCfg::stop_master(){
int i;
for (i=0; i<get_cores_tx(); i++) {
lpt = m_fl.m_threads_info[i];
- CCoreEthIF * erf_vif = &m_cores_vif[i+1];
+ CCoreEthIF * erf_vif = m_cores_vif[i+1];
erf_vif->DumpCoreStats(stdout);
erf_vif->DumpIfStats(stdout);
@@ -4115,9 +4182,10 @@ int CGlobalPortCfg::stop_master(){
dump_post_test_stats(stdout);
m_fl.Delete();
+ return (0);
}
-bool CGlobalPortCfg::is_all_cores_finished(){
+bool CGlobalTRex::is_all_cores_finished(){
int i;
for (i=0; i<get_cores_tx(); i++) {
if ( m_signal[i+1]==0){
@@ -4128,8 +4196,34 @@ bool CGlobalPortCfg::is_all_cores_finished(){
}
+int CGlobalTRex::start_master_stateless(){
+ int i;
+ for (i=0; i<BP_MAX_CORES; i++) {
+ m_signal[i]=0;
+ }
+ m_fl.Create();
+ m_expected_pps = 0;
+ m_expected_cps = 0;
+ m_expected_bps = 0;
+
+ m_fl.generate_p_thread_info(get_cores_tx());
+ CFlowGenListPerThread * lpt;
-int CGlobalPortCfg::start_send_master(){
+ for (i=0; i<get_cores_tx(); i++) {
+ lpt = m_fl.m_threads_info[i];
+ CVirtualIF * erf_vif = m_cores_vif[i+1];
+ lpt->set_vif(erf_vif);
+ lpt->m_node_gen.m_socket_id =m_cores_vif[i+1]->get_socket_id();
+ }
+ m_fl_was_init=true;
+
+ return (0);
+}
+
+
+
+
+int CGlobalTRex::start_send_master(){
int i;
for (i=0; i<BP_MAX_CORES; i++) {
m_signal[i]=0;
@@ -4174,20 +4268,74 @@ int CGlobalPortCfg::start_send_master(){
for (i=0; i<get_cores_tx(); i++) {
lpt = m_fl.m_threads_info[i];
//CNullIF * erf_vif = new CNullIF();
- CVirtualIF * erf_vif = &m_cores_vif[i+1];
+ CVirtualIF * erf_vif = m_cores_vif[i+1];
lpt->set_vif(erf_vif);
/* socket id */
- lpt->m_node_gen.m_socket_id =m_cores_vif[i+1].get_socket_id();
+ lpt->m_node_gen.m_socket_id =m_cores_vif[i+1]->get_socket_id();
}
m_fl_was_init=true;
+ return (0);
}
////////////////////////////////////////////
-static CGlobalPortCfg ports_cfg;
+static CGlobalTRex g_trex;
+
+bool CCoreEthIF::process_rx_pkt(pkt_dir_t dir,
+ rte_mbuf_t * m){
+
+ CSimplePacketParser parser(m);
+ if ( !parser.Parse() ){
+ return false;
+ }
+ bool send=false;
+ CLatencyPktMode *c_l_pkt_mode = g_trex.m_mg.c_l_pkt_mode;
+ bool is_lateancy_pkt = c_l_pkt_mode->IsLatencyPkt(parser.m_ipv4) & parser.IsLatencyPkt(parser.m_l4 + c_l_pkt_mode->l4_header_len());
+
+ if (is_lateancy_pkt){
+ send=true;
+ }else{
+ if ( get_is_rx_filter_enable() ){
+ uint8_t max_ttl = 0xff - get_rx_check_hops();
+ uint8_t pkt_ttl = parser.getTTl();
+ if ( (pkt_ttl==max_ttl) || (pkt_ttl==(max_ttl-1) ) ) {
+ send=true;
+ }
+ }
+ }
+
+
+ if (send) {
+ CGenNodeLatencyPktInfo * node=(CGenNodeLatencyPktInfo * )CGlobalInfo::create_node();
+ if ( node ) {
+ node->m_msg_type = CGenNodeMsgBase::LATENCY_PKT;
+ node->m_dir = dir;
+ node->m_latency_offset = 0xdead;
+ node->m_pkt = m;
+ if ( m_ring_to_rx->Enqueue((CGenNode*)node)==0 ){
+ }else{
+ CGlobalInfo::free_node((CGenNode *)node);
+ send=false;
+ }
+
+ #ifdef LATENCY_QUEUE_TRACE_
+ printf("rx to cp --\n");
+ rte_pktmbuf_dump(stdout,m, rte_pktmbuf_pkt_len(m));
+ #endif
+ }else{
+ send=false;
+ }
+ }
+ return (send);
+}
+
+
+TrexStateless * get_stateless_obj() {
+ return g_trex.m_trex_stateless;
+}
static int latency_one_lcore(__attribute__((unused)) void *dummy)
{
@@ -4196,34 +4344,22 @@ static int latency_one_lcore(__attribute__((unused)) void *dummy)
if ( lpsock->thread_phy_is_latency( phy_id ) ){
- ports_cfg.run_in_laterncy_core();
+ g_trex.run_in_laterncy_core();
}else{
if ( lpsock->thread_phy_is_master( phy_id ) ) {
- ports_cfg.run_in_master();
+ g_trex.run_in_master();
delay(1);
}else{
delay((uint32_t)(1000.0*CGlobalInfo::m_options.m_duration));
/* this core has stopped */
- ports_cfg.m_signal[ lpsock->thread_phy_to_virt( phy_id ) ]=1;
+ g_trex.m_signal[ lpsock->thread_phy_to_virt( phy_id ) ]=1;
}
}
return 0;
}
-static int stateless_entry(__attribute__((unused)) void *dummy) {
- CPlatformSocketInfo * lpsock=&CGlobalInfo::m_socket;
- physical_thread_id_t phy_id = rte_lcore_id();
-
- if (lpsock->thread_phy_is_master( phy_id )) {
- TrexStateless::get_instance().launch_control_plane();
- } else {
- TrexStateless::get_instance().launch_on_dp_core(phy_id);
- }
-
- return (0);
-}
static int slave_one_lcore(__attribute__((unused)) void *dummy)
{
@@ -4232,13 +4368,13 @@ static int slave_one_lcore(__attribute__((unused)) void *dummy)
if ( lpsock->thread_phy_is_latency( phy_id ) ){
- ports_cfg.run_in_laterncy_core();
+ g_trex.run_in_laterncy_core();
}else{
if ( lpsock->thread_phy_is_master( phy_id ) ) {
- ports_cfg.run_in_master();
+ g_trex.run_in_master();
delay(1);
}else{
- ports_cfg.run_in_core( lpsock->thread_phy_to_virt( phy_id ) );
+ g_trex.run_in_core( lpsock->thread_phy_to_virt( phy_id ) );
}
}
return 0;
@@ -4321,15 +4457,13 @@ int update_global_info_from_platform_file(){
CGlobalInfo::m_memory_cfg.set(cg->m_memory,mul);
CGlobalInfo::m_memory_cfg.set_number_of_dp_cors(
- CGlobalInfo::m_options.get_number_of_dp_cores_needed() );
-
+ CGlobalInfo::m_options.get_number_of_dp_cores_needed() );
return (0);
}
int update_dpdk_args(void){
- uint32_t cores_number;
CPlatformSocketInfo * lpsock=&CGlobalInfo::m_socket;
CParserOption * lpop= &CGlobalInfo::m_options;
@@ -4346,7 +4480,7 @@ int update_dpdk_args(void){
}
- sprintf(global_cores_str,"0x%x",lpsock->get_cores_mask());
+ sprintf(global_cores_str,"0x%llx",(unsigned long long)lpsock->get_cores_mask());
/* set the DPDK options */
global_dpdk_args_num =7;
@@ -4397,6 +4531,7 @@ int update_dpdk_args(void){
printf(" %s \n",global_dpdk_args[i]);
}
}
+ return (0);
}
@@ -4418,7 +4553,7 @@ int sim_load_list_of_cap_files(CParserOption * op){
lpt->set_vif(&erf_vif);
if ( (op->preview.getVMode() >1) || op->preview.getFileWrite() ) {
- lpt->generate_erf(op->out_file,op->preview);
+ lpt->start_generate_stateful(op->out_file,op->preview);
}
lpt->m_node_gen.DumpHist(stdout);
@@ -4430,42 +4565,6 @@ int sim_load_list_of_cap_files(CParserOption * op){
}
-
-
-static int
-launch_stateless_trex() {
- CPlatformSocketInfo *lpsock=&CGlobalInfo::m_socket;
- CParserOption *lpop= &CGlobalInfo::m_options;
- CPlatformYamlInfo *cg=&global_platform_cfg_info;
-
- TrexStatelessCfg cfg;
-
- TrexRpcServerConfig rpc_req_resp_cfg(TrexRpcServerConfig::RPC_PROT_TCP, 5050);
- TrexRpcServerConfig rpc_async_cfg(TrexRpcServerConfig::RPC_PROT_TCP, 5051);
-
- cfg.m_dp_core_count = lpop->preview.getCores();
- cfg.m_port_count = lpop->m_expected_portd;
- cfg.m_rpc_req_resp_cfg = &rpc_req_resp_cfg;
- cfg.m_rpc_async_cfg = &rpc_async_cfg;
- cfg.m_rpc_server_verbose = true;
-
- TrexStateless::configure(cfg);
-
- printf("\nStarting T-Rex Stateless\n");
- printf("Starting RPC Server...\n\n");
-
- rte_eal_mp_remote_launch(stateless_entry, NULL, CALL_MASTER);
-
- unsigned lcore_id;
- RTE_LCORE_FOREACH_SLAVE(lcore_id) {
- if (rte_eal_wait_lcore(lcore_id) < 0)
- return -1;
- }
- return (0);
-}
-
-
-
int main_test(int argc , char * argv[]){
utl_termio_init();
@@ -4525,78 +4624,61 @@ int main_test(int argc , char * argv[]){
return ( sim_load_list_of_cap_files(&CGlobalInfo::m_options) );
}
- bool is_stateless = (CGlobalInfo::m_options.m_run_mode == CParserOption::RUN_MODE_INTERACTIVE);
-
- if ( !ports_cfg.Create(is_stateless) ){
+ if ( !g_trex.Create() ){
exit(1);
}
- /* patch here */
- if (is_stateless) {
- return launch_stateless_trex();
- }
-
-
if (po->preview.get_is_rx_check_enable() && (po->m_rx_check_sampe< get_min_sample_rate()) ) {
po->m_rx_check_sampe = get_min_sample_rate();
printf("Warning rx check sample rate should be lower than %d setting it to %d\n",get_min_sample_rate(),get_min_sample_rate());
}
/* set dump mode */
- ports_cfg.m_io_modes.set_mode((CTrexGlobalIoMode::CliDumpMode)CGlobalInfo::m_options.m_io_mode);
+ g_trex.m_io_modes.set_mode((CTrexGlobalIoMode::CliDumpMode)CGlobalInfo::m_options.m_io_mode);
if ( !CGlobalInfo::m_options.is_latency_disabled()
&& (CGlobalInfo::m_options.m_latency_prev>0) ){
uint32_t pkts = CGlobalInfo::m_options.m_latency_prev*
CGlobalInfo::m_options.m_latency_rate;
- printf("Start prev latency check - hack for Keren for %d sec \n",CGlobalInfo::m_options.m_latency_prev);
- ports_cfg.m_mg.start(pkts);
- printf("Delay now you can call command \n");
+ printf("Start prev latency check- for %d sec \n",CGlobalInfo::m_options.m_latency_prev);
+ g_trex.m_mg.start(pkts);
delay(CGlobalInfo::m_options.m_latency_prev* 1000);
- printf("Finish wating \n");
- ports_cfg.m_mg.reset();
- ports_cfg.reset_counters();
+ printf("Finished \n");
+ g_trex.m_mg.reset();
+ g_trex.reset_counters();
}
- ports_cfg.start_send_master();
+ if ( get_is_stateless() ) {
+ g_trex.start_master_stateless();
- // TBD remove
- //ports_cfg.test_latency();
- /* test seding */
- //while (1) {
- //}
+ }else{
+ g_trex.start_send_master();
+ }
/* TBD_FDIR */
#if 0
printf(" test_send \n");
- ports_cfg.test_send();
+ g_trex.test_send();
while (1) {
delay(10000);
}
#endif
-
-
-
- //ports_cfg.test_latency();
- //return (0);
-
-
if ( CGlobalInfo::m_options.preview.getOnlyLatency() ){
rte_eal_mp_remote_launch(latency_one_lcore, NULL, CALL_MASTER);
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (rte_eal_wait_lcore(lcore_id) < 0)
return -1;
}
- ports_cfg.stop_master();
+ g_trex.stop_master();
return (0);
}
if ( CGlobalInfo::m_options.preview.getSingleCore() ) {
- ports_cfg.run_in_core(1);
- ports_cfg.stop_master();
+ g_trex.run_in_core(1);
+ g_trex.stop_master();
return (0);
}
@@ -4606,8 +4688,8 @@ int main_test(int argc , char * argv[]){
return -1;
}
- ports_cfg.stop_master();
- ports_cfg.Delete();
+ g_trex.stop_master();
+ g_trex.Delete();
utl_termio_reset();
return (0);
@@ -4634,15 +4716,19 @@ int CTRexExtendedDriverBase1G::wait_for_stable_link(){
}
int CTRexExtendedDriverBase1G::configure_drop_queue(CPhyEthIF * _if){
+ uint8_t protocol;
+ if (CGlobalInfo::m_options.m_l_pkt_mode == 0) {
+ protocol = IPPROTO_SCTP;
+ } else {
+ protocol = IPPROTO_ICMP;
+ }
+
_if->pci_reg_write( E1000_RXDCTL(0) , 0);
/* enable filter to pass packet to rx queue 1 */
-
_if->pci_reg_write( E1000_IMIR(0), 0x00020000);
-
_if->pci_reg_write( E1000_IMIREXT(0), 0x00081000);
-
- _if->pci_reg_write( E1000_TTQF(0), 0x00000084 /* protocol */
+ _if->pci_reg_write( E1000_TTQF(0), protocol
| 0x00008100 /* enable */
| 0xE0010000 /* RX queue is 1 */
);
@@ -4670,11 +4756,13 @@ int CTRexExtendedDriverBase1G::configure_rx_filter_rules(CPhyEthIF * _if){
*/
int i;
// IPv4: bytes being compared are {TTL, Protocol}
- uint16_t ff_rules_v4[4]={
+ uint16_t ff_rules_v4[6]={
(uint16_t)(0xFF06 - v4_hops),
(uint16_t)(0xFE11 - v4_hops),
(uint16_t)(0xFF11 - v4_hops),
(uint16_t)(0xFE06 - v4_hops),
+ (uint16_t)(0xFF01 - v4_hops),
+ (uint16_t)(0xFE01 - v4_hops),
} ;
// IPv6: bytes being compared are {NextHdr, HopLimit}
uint16_t ff_rules_v6[2]={
@@ -4732,14 +4820,13 @@ int CTRexExtendedDriverBase1G::configure_rx_filter_rules(CPhyEthIF * _if){
/* enable all rules */
_if->pci_reg_write(E1000_WUFC, (mask<<16) | (1<<14) );
+
+ return (0);
}
void CTRexExtendedDriverBase1G::get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats){
- int i;
- uint64_t t=0;
-
stats->ipackets += _if->pci_reg_read(E1000_GPRC) ;
stats->ibytes += (_if->pci_reg_read(E1000_GORCL) );
@@ -4816,24 +4903,30 @@ int CTRexExtendedDriverBase10G::configure_rx_filter_rules(CPhyEthIF * _if){
// IPv4: bytes being compared are {TTL, Protocol}
- uint16_t ff_rules_v4[4]={
+ uint16_t ff_rules_v4[6]={
(uint16_t)(0xFF11 - v4_hops),
(uint16_t)(0xFE11 - v4_hops),
(uint16_t)(0xFF06 - v4_hops),
(uint16_t)(0xFE06 - v4_hops),
+ (uint16_t)(0xFF01 - v4_hops),
+ (uint16_t)(0xFE01 - v4_hops),
} ;
// IPv6: bytes being compared are {NextHdr, HopLimit}
- uint16_t ff_rules_v6[4]={
+ uint16_t ff_rules_v6[6]={
+ (uint16_t)(0x3CFF - hops),
+ (uint16_t)(0x3CFE - hops),
(uint16_t)(0x3CFF - hops),
(uint16_t)(0x3CFE - hops),
(uint16_t)(0x3CFF - hops),
(uint16_t)(0x3CFE - hops),
} ;
- const rte_l4type ff_rules_type[4]={
+ const rte_l4type ff_rules_type[6]={
RTE_FDIR_L4TYPE_UDP,
RTE_FDIR_L4TYPE_UDP,
RTE_FDIR_L4TYPE_TCP,
- RTE_FDIR_L4TYPE_TCP
+ RTE_FDIR_L4TYPE_TCP,
+ RTE_FDIR_L4TYPE_NONE,
+ RTE_FDIR_L4TYPE_NONE
} ;
uint16_t *ff_rules;
@@ -4869,11 +4962,11 @@ int CTRexExtendedDriverBase10G::configure_rx_filter_rules(CPhyEthIF * _if){
rte_exit(EXIT_FAILURE, " ERROR rte_eth_dev_fdir_add_perfect_filter : %d\n",res);
}
}
+ return (0);
}
int CTRexExtendedDriverBase10G::configure_drop_queue(CPhyEthIF * _if){
-
- /* enable rule 0 SCTP -> queue 1 for latency */
+ /* enable rule 0 SCTP -> queue 1 for latency */
/* 1<<21 means that queue 1 is for SCTP */
_if->pci_reg_write(IXGBE_L34T_IMIR(0),(1<<21));
@@ -4883,7 +4976,6 @@ int CTRexExtendedDriverBase10G::configure_drop_queue(CPhyEthIF * _if){
((0x0f)<<IXGBE_FTQF_5TUPLE_MASK_SHIFT)|IXGBE_FTQF_QUEUE_ENABLE);
/* disable queue zero - default all traffic will go to here and will be dropped */
-
_if->pci_reg_write( IXGBE_RXDCTL(0) , 0);
return (0);
}
@@ -4944,7 +5036,7 @@ void CTRexExtendedDriverBase40G::update_configuration(port_cfg_t * cfg){
}
-
+/* Add rule to send packets with protocol 'type', and ttl 'ttl' to rx queue 1 */
void CTRexExtendedDriverBase40G::add_rules(CPhyEthIF * _if,
enum rte_eth_flow_type type,
uint8_t ttl){
@@ -4969,7 +5061,11 @@ void CTRexExtendedDriverBase40G::add_rules(CPhyEthIF * _if,
filter.input.flow_type = type;
filter.input.ttl=ttl;
- /* any SCTP move to queue number 1 */
+ if (type == RTE_ETH_FLOW_TYPE_IPV4_OTHER) {
+ filter.input.flow.ip4_flow.l4_proto = IPPROTO_ICMP; // In this case we want filter for icmp packets
+ }
+
+ /* We want to place latency packets in queue 1 */
ret=rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR,
RTE_ETH_FILTER_ADD, (void*)&filter);
@@ -4991,12 +5087,16 @@ int CTRexExtendedDriverBase40G::configure_rx_filter_rules(CPhyEthIF * _if){
add_rules(_if,RTE_ETH_FLOW_TYPE_UDPV6,ttl);
add_rules(_if,RTE_ETH_FLOW_TYPE_TCPV6,ttl);
}
+
+ return (0);
}
int CTRexExtendedDriverBase40G::configure_drop_queue(CPhyEthIF * _if){
- add_rules(_if,RTE_ETH_FLOW_TYPE_SCTPV4,0);
+ /* Configure queue for latency packets */
+ add_rules(_if,RTE_ETH_FLOW_TYPE_IPV4_OTHER,255);
+ add_rules(_if,RTE_ETH_FLOW_TYPE_SCTPV4,255);
return (0);
}
@@ -5146,3 +5246,62 @@ struct rte_mbuf * rte_mbuf_convert_to_one_seg(struct rte_mbuf *m){
}
+/***********************************************************
+ * platfrom API object
+ * TODO: REMOVE THIS TO A SEPERATE FILE
+ *
+ **********************************************************/
+void
+TrexDpdkPlatformApi::get_global_stats(TrexPlatformGlobalStats &stats) const {
+ CGlobalStats trex_stats;
+ g_trex.get_stats(trex_stats);
+
+ stats.m_stats.m_cpu_util = trex_stats.m_cpu_util;
+
+ stats.m_stats.m_tx_bps = trex_stats.m_tx_bps;
+ stats.m_stats.m_tx_pps = trex_stats.m_tx_pps;
+ stats.m_stats.m_total_tx_pkts = trex_stats.m_total_tx_pkts;
+ stats.m_stats.m_total_tx_bytes = trex_stats.m_total_tx_bytes;
+
+ stats.m_stats.m_rx_bps = trex_stats.m_rx_bps;
+ stats.m_stats.m_rx_pps = /*trex_stats.m_rx_pps*/ 0; /* missing */
+ stats.m_stats.m_total_rx_pkts = trex_stats.m_total_rx_pkts;
+ stats.m_stats.m_total_rx_bytes = trex_stats.m_total_rx_bytes;
+}
+
+void
+TrexDpdkPlatformApi::get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const {
+
+}
+
+uint8_t
+TrexDpdkPlatformApi::get_dp_core_count() const {
+ return CGlobalInfo::m_options.preview.getCores();
+}
+
+
+void
+TrexDpdkPlatformApi::port_id_to_cores(uint8_t port_id, std::vector<std::pair<uint8_t, uint8_t>> &cores_id_list) const {
+
+ cores_id_list.clear();
+
+ /* iterate over all DP cores */
+ for (uint8_t core_id = 0; core_id < g_trex.get_cores_tx(); core_id++) {
+
+ /* iterate over all the directions*/
+ for (uint8_t dir = 0 ; dir < CS_NUM; dir++) {
+ if (g_trex.m_cores_vif[core_id + 1]->get_ports()[dir].m_port->get_port_id() == port_id) {
+ cores_id_list.push_back(std::make_pair(core_id, dir));
+ }
+ }
+ }
+}
+
+void
+TrexDpdkPlatformApi::get_interface_info(uint8_t interface_id,
+ std::string &driver_name,
+ driver_speed_e &speed) const {
+
+ driver_name = CTRexExtendedDriverDb::Ins()->get_driver_name();
+ speed = CTRexExtendedDriverDb::Ins()->get_drv()->get_driver_speed();
+}