diff options
author | Hanoh Haim <hhaim@cisco.com> | 2016-01-05 20:51:47 +0200 |
---|---|---|
committer | Hanoh Haim <hhaim@cisco.com> | 2016-01-05 20:51:47 +0200 |
commit | 5f07d1062309eea31e47a6d9ab23bb1c94de5c83 (patch) | |
tree | 667326ce482b79d9626badb80d8562a9ecf7551b /src | |
parent | c905d6b0845e79dbc5d5d37eee560d1dbc58b6ff (diff) | |
parent | d6be4b0e8a2cd92b5e6c455532431897f76331fe (diff) |
Merge branch 'random_pkt'
Diffstat (limited to 'src')
-rwxr-xr-x | src/bp_sim.cpp | 46 | ||||
-rwxr-xr-x | src/bp_sim.h | 49 | ||||
-rwxr-xr-x | src/common/captureFile.h | 2 | ||||
-rw-r--r-- | src/gtest/trex_stateless_gtest.cpp | 198 | ||||
-rwxr-xr-x | src/main_dpdk.cpp | 134 | ||||
-rwxr-xr-x | src/platform_cfg.cpp | 35 | ||||
-rwxr-xr-x | src/platform_cfg.h | 38 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 17 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmds.h | 2 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream.h | 6 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.cpp | 94 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.h | 100 | ||||
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.cpp | 34 | ||||
-rw-r--r-- | src/stateless/dp/trex_stream_node.h | 12 |
14 files changed, 668 insertions, 99 deletions
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index d08e61c8..fcef049c 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -66,7 +66,7 @@ void CGlobalMemory::Dump(FILE *fd){ int i=0; for (i=0; i<MBUF_SIZE; i++) { - if ( (i>MBUF_2048) && (i<MBUF_DP_FLOWS)){ + if ( (i>MBUF_9k) && (i<MBUF_DP_FLOWS)){ continue; } if ( i<TRAFFIC_MBUF_64 ){ @@ -95,6 +95,8 @@ void CGlobalMemory::set(const CPlatformMemoryYamlInfo &info,float mul){ m_mbuf[MBUF_512] += info.m_mbuf[TRAFFIC_MBUF_512]; m_mbuf[MBUF_1024] += info.m_mbuf[TRAFFIC_MBUF_1024]; m_mbuf[MBUF_2048] += info.m_mbuf[TRAFFIC_MBUF_2048]; + m_mbuf[MBUF_4096] += info.m_mbuf[TRAFFIC_MBUF_4096]; + m_mbuf[MBUF_9k] += info.m_mbuf[MBUF_9k]; } @@ -494,7 +496,10 @@ void CRteMemPool::dump(FILE *fd){ DUMP_MBUF("mbuf_256",m_mbuf_pool_256); DUMP_MBUF("mbuf_512",m_mbuf_pool_512); DUMP_MBUF("mbuf_1024",m_mbuf_pool_1024); - DUMP_MBUF("mbuf_2048",m_big_mbuf_pool); + DUMP_MBUF("mbuf_2048",m_mbuf_pool_2048); + DUMP_MBUF("mbuf_4096",m_mbuf_pool_4096); + DUMP_MBUF("mbuf_9k",m_mbuf_pool_9k); + } //////////////////////////////////////// @@ -506,12 +511,14 @@ void CGlobalInfo::free_pools(){ for (i=0; i<(int)MAX_SOCKETS_SUPPORTED; i++) { if (lpSocket->is_sockets_enable((socket_id_t)i)) { lpmem= &m_mem_pool[i]; - utl_rte_mempool_delete(lpmem->m_big_mbuf_pool); utl_rte_mempool_delete(lpmem->m_small_mbuf_pool); utl_rte_mempool_delete(lpmem->m_mbuf_pool_128); utl_rte_mempool_delete(lpmem->m_mbuf_pool_256); utl_rte_mempool_delete(lpmem->m_mbuf_pool_512); utl_rte_mempool_delete(lpmem->m_mbuf_pool_1024); + utl_rte_mempool_delete(lpmem->m_mbuf_pool_2048); + utl_rte_mempool_delete(lpmem->m_mbuf_pool_4096); + utl_rte_mempool_delete(lpmem->m_mbuf_pool_9k); } utl_rte_mempool_delete(m_mem_pool[0].m_mbuf_global_nodes); } @@ -531,12 +538,6 @@ void CGlobalInfo::init_pools(uint32_t rx_buffers){ lpmem= &m_mem_pool[i]; lpmem->m_pool_id=i; - lpmem->m_big_mbuf_pool = utl_rte_mempool_create("big-pkt-const", - (lp->get_2k_num_blocks()+rx_buffers), - CONST_MBUF_SIZE, - 32, - (i<<5)+ 1,i); - assert(lpmem->m_big_mbuf_pool); /* this include the packet from 0-64 this is for small packets */ lpmem->m_small_mbuf_pool =utl_rte_mempool_create("small-pkt-const", @@ -577,6 +578,26 @@ void CGlobalInfo::init_pools(uint32_t rx_buffers){ assert(lpmem->m_mbuf_pool_1024); + lpmem->m_mbuf_pool_2048=utl_rte_mempool_create("_2048-pkt-const", + lp->m_mbuf[MBUF_2048], + CONST_2048_MBUF_SIZE, + 32,(i<<5)+ 5,i); + + assert(lpmem->m_mbuf_pool_2048); + + lpmem->m_mbuf_pool_4096=utl_rte_mempool_create("_4096-pkt-const", + lp->m_mbuf[MBUF_4096], + CONST_4096_MBUF_SIZE, + 32,(i<<5)+ 5,i); + + assert(lpmem->m_mbuf_pool_4096); + + lpmem->m_mbuf_pool_9k=utl_rte_mempool_create("_9k-pkt-const", + lp->m_mbuf[MBUF_9k]+rx_buffers, + CONST_9k_MBUF_SIZE, + 32,(i<<5)+ 5,i); + + assert(lpmem->m_mbuf_pool_9k); } } @@ -1190,9 +1211,9 @@ void CPacketIndication::ProcessIpPacket(CPacketParser *parser, return; } - if ( m_packet->pkt_len > MAX_BUF_SIZE -FIRST_PKT_SIZE ){ + if ( m_packet->pkt_len > MAX_PKT_SIZE ){ m_cnt->m_tcp_udp_pkt_length_error++; - printf("ERROR packet is too big, not supported jumbo packets that larger than %d \n",MAX_BUF_SIZE); + printf("ERROR packet is too big, not supported jumbo packets that larger than %d \n",MAX_PKT_SIZE); return; } @@ -1200,9 +1221,6 @@ void CPacketIndication::ProcessIpPacket(CPacketParser *parser, m_packet->pkt_len = l3.m_ipv4->getTotalLength() + getIpOffset(); if (m_packet->pkt_len < 60) { m_packet->pkt_len = 60; } - - - m_cnt->m_valid_udp_tcp++; m_payload_len = l3.m_ipv4->getTotalLength() - (payload_offset_from_ip); m_payload = (uint8_t *)(packetBase +offset); diff --git a/src/bp_sim.h b/src/bp_sim.h index e0792336..4b906912 100755 --- a/src/bp_sim.h +++ b/src/bp_sim.h @@ -411,10 +411,6 @@ public: #define CONST_NB_MBUF 16380 - -#define MAX_BUF_SIZE (2048) -#define CONST_MBUF_SIZE (MAX_BUF_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) - /* this is the first small part of the packet that we manipulate */ #define FIRST_PKT_SIZE 64 #define CONST_SMALL_MBUF_SIZE (FIRST_PKT_SIZE + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) @@ -424,13 +420,19 @@ public: #define _256_MBUF_SIZE 256 #define _512_MBUF_SIZE 512 #define _1024_MBUF_SIZE 1024 +#define _2048_MBUF_SIZE 2048 +#define _4096_MBUF_SIZE 4096 +#define MAX_PKT_ALIGN_BUF_9K (9*1024+64) +#define MBUF_PKT_PREFIX ( sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM ) - -#define CONST_128_MBUF_SIZE (128 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) -#define CONST_256_MBUF_SIZE (256 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) -#define CONST_512_MBUF_SIZE (512 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) -#define CONST_1024_MBUF_SIZE (1024 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) +#define CONST_128_MBUF_SIZE (128 + MBUF_PKT_PREFIX ) +#define CONST_256_MBUF_SIZE (256 + MBUF_PKT_PREFIX ) +#define CONST_512_MBUF_SIZE (512 + MBUF_PKT_PREFIX) +#define CONST_1024_MBUF_SIZE (1024 + MBUF_PKT_PREFIX) +#define CONST_2048_MBUF_SIZE (2048 + MBUF_PKT_PREFIX) +#define CONST_4096_MBUF_SIZE (4096 + MBUF_PKT_PREFIX) +#define CONST_9k_MBUF_SIZE (MAX_PKT_ALIGN_BUF_9K + MBUF_PKT_PREFIX) class CPreviewMode { @@ -1118,9 +1120,13 @@ public: m = _rte_pktmbuf_alloc(m_mbuf_pool_512); }else if (size < _1024_MBUF_SIZE) { m = _rte_pktmbuf_alloc(m_mbuf_pool_1024); + }else if (size < _2048_MBUF_SIZE) { + m = _rte_pktmbuf_alloc(m_mbuf_pool_2048); + }else if (size < _4096_MBUF_SIZE) { + m = _rte_pktmbuf_alloc(m_mbuf_pool_4096); }else{ - assert(size<MAX_BUF_SIZE); - m = _rte_pktmbuf_alloc(m_big_mbuf_pool); + assert(size<MAX_PKT_ALIGN_BUF_9K); + m = _rte_pktmbuf_alloc(m_mbuf_pool_9k); } return (m); } @@ -1129,21 +1135,22 @@ public: return ( _rte_pktmbuf_alloc(m_small_mbuf_pool) ); } - inline rte_mbuf_t * pktmbuf_alloc_big(){ - return ( _rte_pktmbuf_alloc(m_big_mbuf_pool) ); - } void dump(FILE *fd); void dump_in_case_of_error(FILE *fd); public: - rte_mempool_t * m_big_mbuf_pool; /* pool for const packets */ rte_mempool_t * m_small_mbuf_pool; /* pool for start packets */ + rte_mempool_t * m_mbuf_pool_128; rte_mempool_t * m_mbuf_pool_256; rte_mempool_t * m_mbuf_pool_512; rte_mempool_t * m_mbuf_pool_1024; + rte_mempool_t * m_mbuf_pool_2048; + rte_mempool_t * m_mbuf_pool_4096; + rte_mempool_t * m_mbuf_pool_9k; + rte_mempool_t * m_mbuf_global_nodes; uint32_t m_pool_id; }; @@ -1162,11 +1169,7 @@ public: return ( m_mem_pool[socket].pktmbuf_alloc_small() ); } - static inline rte_mbuf_t * pktmbuf_alloc_big(socket_id_t socket){ - return ( m_mem_pool[socket].pktmbuf_alloc_big() ); - } - - + /** * try to allocate small buffers too @@ -3102,7 +3105,11 @@ public: SIZE_512 = 512, SIZE_1024 = 1024, SIZE_2048 = 2048, - MASK_SIZE =6 + SIZE_4096 = 4096, + SIZE_8192 = 8192, + SIZE_16384 = 16384, + + MASK_SIZE =9 }; void clear(){ diff --git a/src/common/captureFile.h b/src/common/captureFile.h index 027f1fcf..16a6120b 100755 --- a/src/common/captureFile.h +++ b/src/common/captureFile.h @@ -35,7 +35,7 @@ typedef enum capture_type { LAST_TYPE } capture_type_e; -#define MAX_PKT_SIZE (2048) +#define MAX_PKT_SIZE (9*1024+22) /* 9k IP +14+4 FCS +some spare */ #define READER_MAX_PACKET_SIZE MAX_PKT_SIZE diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp index 73b7536a..70f397b1 100644 --- a/src/gtest/trex_stateless_gtest.cpp +++ b/src/gtest/trex_stateless_gtest.cpp @@ -22,6 +22,7 @@ limitations under the License. #include "bp_sim.h" #include <common/gtest.h> #include <common/basic_utils.h> +#include <trex_stateless.h> #include <trex_stateless_dp_core.h> #include <trex_stateless_messaging.h> #include <trex_streams_compiler.h> @@ -1027,6 +1028,203 @@ TEST_F(basic_vm, vm_syn_attack) { } +void run_vm_program( StreamVm & vm, + std::string input_pcap_file, + std::string out_file_name, + int num_pkts + ){ + + CPcapLoader pcap; + pcap.load_pcap_file(input_pcap_file,0); + + printf(" packet size : %lu \n",(ulong)pcap.m_raw.pkt_len); + vm.compile(pcap.m_raw.pkt_len); + + StreamVmDp * lpDpVm =vm.generate_dp_object(); + + uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size(); + + printf (" program size : %lu \n",(ulong)program_size); + + vm.Dump(stdout); + + std::string out_file_full ="exp/"+out_file_name +".pcap"; + std::string out_file_ex_full ="exp/"+out_file_name +"-ex.pcap"; + + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)out_file_full.c_str()); + assert(lpWriter); + + + StreamDPVmInstructionsRunner runner; + + uint32_t random_per_thread=0; + + int i; + for (i=0; i<num_pkts; i++) { + + runner.run(&random_per_thread, + lpDpVm->get_program_size(), + lpDpVm->get_program(), + lpDpVm->get_bss(), + (uint8_t*)pcap.m_raw.raw); + uint16_t new_pkt_size=runner.get_new_pkt_size(); + assert(new_pkt_size>0); + if (new_pkt_size ==0) { + assert(lpWriter->write_packet(&pcap.m_raw)); + }else{ + /* we can only reduce */ + if (new_pkt_size>pcap.m_raw.pkt_len) { + new_pkt_size=pcap.m_raw.pkt_len; + } + CCapPktRaw np(new_pkt_size); + np.time_sec = pcap.m_raw.time_sec; + np.time_nsec = pcap.m_raw.time_nsec; + np.pkt_cnt = pcap.m_raw.pkt_cnt; + memcpy(np.raw,pcap.m_raw.raw,new_pkt_size); + assert(lpWriter->write_packet(&np)); + } + } + + delete lpWriter; + + CErfCmp cmp; + delete lpDpVm; + + bool res1=cmp.compare(out_file_full.c_str() ,out_file_ex_full.c_str()); + EXPECT_EQ(1, res1?1:0); +} + + +TEST_F(basic_vm, vm_inc_size_64_128) { + + StreamVm vm; + + vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var", + 2, // size var must be 16bit size + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC, + 127, + 128, + 256)); + + vm.add_instruction( new StreamVmInstructionChangePktSize( "rand_pkt_size_var")); + + /* src ip */ + /*14+ 2 , remove the */ + + vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",16, -14,true) + ); + + vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) ); + + /* update UDP length */ + vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",32+6, -(14+20),true) + ); + + run_vm_program(vm,"stl/udp_1518B_no_crc.pcap","stl_vm_inc_size_64_128",20); +} + +TEST_F(basic_vm, vm_random_size_64_128) { + + StreamVm vm; + srand(0x1234); + + vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var", + 2, // size var must be 16bit size + StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM, + 0, + 128, + 256)); + + vm.add_instruction( new StreamVmInstructionChangePktSize( "rand_pkt_size_var")); + + /* src ip */ + /*14+ 2 , remove the */ + + vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",16, -14,true) + ); + + vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) ); + + /* update UDP length */ + vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",32+6, -(14+20),true) + ); + + + run_vm_program(vm,"stl/udp_1518B_no_crc.pcap","stl_vm_rand_size_64_128",20); + +} + + + +/* should have exception packet size is smaller than range */ +TEST_F(basic_vm, vm_random_size_64_127_128) { + + StreamVm vm; + srand(0x1234); + + vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var", + 2, // size var must be 16bit size + StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM, + 127, + 128, + 256)); + + vm.add_instruction( new StreamVmInstructionChangePktSize( "rand_pkt_size_var")); + + /* src ip */ + /*14+ 2 , remove the */ + + vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",16, -14,true) + ); + + vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) ); + + /* update UDP length */ + vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",32+6, -(14+20),true) + ); + + bool fail=false; + + try { + run_vm_program(vm,"stl/udp_64B_no_crc.pcap","stl_vm_rand_size_64B_127_128",20); + } catch (const TrexException &ex) { + fail=true; + } + + EXPECT_EQ(true, fail); + +} + + +TEST_F(basic_vm, vm_random_size_500b_0_9k) { + + StreamVm vm; + srand(0x1234); + + vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var", + 2, // size var must be 16bit size + StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM, + 0, + 0, + 9*1024)); + + vm.add_instruction( new StreamVmInstructionChangePktSize( "rand_pkt_size_var")); + + /* src ip */ + /*14+ 2 , remove the */ + + vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",16, -14,true) + ); + + vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) ); + + /* update UDP length */ + vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",32+6, -(14+20),true) + ); + + run_vm_program(vm,"stl/udp_594B_no_crc.pcap","stl_vm_rand_size_512B_64_128",10); + +} diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 0d534b2e..3a31945f 100755 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -1017,7 +1017,7 @@ struct port_cfg_t { m_tx_conf.tx_thresh.wthresh = TX_WTHRESH; m_port_conf.rxmode.jumbo_frame=1; - m_port_conf.rxmode.max_rx_pkt_len =2000; + m_port_conf.rxmode.max_rx_pkt_len =9*1024+22; m_port_conf.rxmode.hw_strip_crc=1; } @@ -2069,10 +2069,12 @@ int CCoreEthIF::send_pkt(CCorePerPort * lp_port, CVirtualIFPerSideStats * lp_stats ){ + //printf(" %lu \n",(ulong)rte_pktmbuf_pkt_len(m)); //rte_pktmbuf_dump(stdout,m, rte_pktmbuf_pkt_len(m)); - lp_stats->m_tx_pkt +=1; - lp_stats->m_tx_bytes += (rte_pktmbuf_pkt_len(m)+4); + /* too expensive remove this for now */ + //lp_stats->m_tx_pkt +=1; + //lp_stats->m_tx_bytes += (rte_pktmbuf_pkt_len(m)+4); uint16_t len = lp_port->m_len; lp_port->m_table[len]=m; @@ -2137,6 +2139,7 @@ int CCoreEthIFStateless::send_node(CGenNode * no){ m=node_sl->alloc_node_with_vm(); assert(m); } + send_pkt(lp_port,m,lp_stats); return (0); @@ -2796,9 +2799,17 @@ private: int pkt, int port); + int test_send_one_pkt(rte_mbuf_t *m, + uint16_t queue_id, + int port); int create_pkt(uint8_t *pkt,int pkt_size); + rte_mbuf_t * create_pkt_indirect(uint32_t new_pkt_size); + int create_udp_pkt(); + int create_udp_9k_pkt(); + + int create_icmp_pkt(); @@ -2914,24 +2925,49 @@ int CGlobalTRex::rcv_send_all(int queue_id){ int CGlobalTRex::test_send(){ - int i; + //int i; set_promisc_all(true); - create_udp_pkt(); + create_udp_9k_pkt(); + assert(m_test); - CRx_check_header rx_check_header; - (void)rx_check_header; + rte_mbuf_t * d= create_pkt_indirect(9*1024+18); + test_send_one_pkt(d,0,0); - 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; - rx_check_header.m_magic=2; - rx_check_header.m_pkt_id=7; - rx_check_header.m_flow_id=9; - rx_check_header.m_flags=11; + + //d= create_pkt_indirect(200); + //test_send_one_pkt(d,0,0); + + printf(" ---------\n"); + printf(" rx queue 0 \n"); + printf(" ---------\n"); + rcv_send_all(0); + printf("\n\n"); + + printf(" ---------\n"); + printf(" rx queue 1 \n"); + printf(" ---------\n"); + rcv_send_all(1); + printf(" ---------\n"); + + delay(1000); + + int j=0; + for (j=0; j<m_max_ports; j++) { + CPhyEthIF * lp=&m_ports[j]; + printf(" port : %d \n",j); + printf(" ----------\n"); + + lp->update_counters(); + lp->get_stats().Dump(stdout); + lp->dump_stats_extended(stdout); + } + + return (0); + +#if 0 - assert(m_test); for (i=0; i<1; i++) { //test_send_pkts(0,1,0); //test_send_pkts(m_latency_tx_queue_id,12,0); @@ -2939,7 +2975,6 @@ int CGlobalTRex::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,2,1); /*delay(1000); fprintf(stdout," --------------------------------\n"); @@ -2985,7 +3020,9 @@ int CGlobalTRex::test_send(){ #endif fprintf(stdout," drop : %llu \n", (unsigned long long)m_test_drop); + return (0); + #endif } @@ -3052,9 +3089,8 @@ const uint8_t icmp_pkt1[]={ 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); + rte_mbuf_t * m= CGlobalInfo::pktmbuf_alloc(0,pkt_size); if ( unlikely(m==0) ) { printf("ERROR no packets \n"); return (0); @@ -3063,22 +3099,56 @@ int CGlobalTRex::create_pkt(uint8_t *pkt,int pkt_size){ assert(p); /* set pkt data */ memcpy(p,pkt,pkt_size); - //m->ol_flags = PKT_TX_VLAN_PKT; - //m->pkt.vlan_tci =200; - m_test = m; - return (0); } +rte_mbuf_t * CGlobalTRex::create_pkt_indirect(uint32_t new_pkt_size){ + + rte_mbuf_t * d= CGlobalInfo::pktmbuf_alloc(0,60); + assert(d); + rte_pktmbuf_attach(d,m_test); + d->data_len =new_pkt_size; + d->pkt_len =new_pkt_size; + return (d); +} + int CGlobalTRex::create_udp_pkt(){ return (create_pkt((uint8_t*)udp_pkt,sizeof(udp_pkt))); } +int CGlobalTRex::create_udp_9k_pkt(){ + uint16_t pkt_size=9*1024+21; + uint8_t *p=(uint8_t *)malloc(9*1024+22); + assert(p); + memset(p,0x55,pkt_size); + memcpy(p,(uint8_t*)udp_pkt,sizeof(udp_pkt)); + create_pkt(p,pkt_size); + free(p); + return (0); +} + + + int CGlobalTRex::create_icmp_pkt(){ return (create_pkt((uint8_t*)icmp_pkt1,sizeof(icmp_pkt1))); } +int CGlobalTRex::test_send_one_pkt(rte_mbuf_t *m, + uint16_t queue_id, + int port){ + + CPhyEthIF * lp=&m_ports[port]; + rte_mbuf_t * tx_pkts[1]; + tx_pkts[0]=m; + + uint16_t res=lp->tx_burst(queue_id,tx_pkts,1); + if ((1-res)>0) { + m_test_drop+=(1-res); + } + return (0); +} + /* test by sending 10 packets ...*/ int CGlobalTRex::test_send_pkts(uint16_t queue_id, @@ -3290,6 +3360,11 @@ int CGlobalTRex::ixgbe_start(void){ /* last TX queue if for latency check */ if ( get_vm_one_queue_enable() ) { /* one tx one rx */ + + /* VMXNET3 does claim to support 16K but somehow does not work */ + /* reduce to 2000 */ + m_port_cfg.m_port_conf.rxmode.max_rx_pkt_len = 2000; + _if->configure(1, 1, &m_port_cfg.m_port_conf); @@ -3298,7 +3373,7 @@ int CGlobalTRex::ixgbe_start(void){ 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); - assert(CGlobalInfo::m_mem_pool[socket_id].m_big_mbuf_pool); + assert(CGlobalInfo::m_mem_pool[socket_id].m_mbuf_pool_2048); @@ -3307,7 +3382,7 @@ int CGlobalTRex::ixgbe_start(void){ RTE_TEST_RX_DESC_VM_DEFAULT, socket_id, &m_port_cfg.m_rx_conf, - CGlobalInfo::m_mem_pool[socket_id].m_big_mbuf_pool); + CGlobalInfo::m_mem_pool[socket_id].m_mbuf_pool_2048); int qid; for ( qid=0; qid<(m_max_queues_per_port); qid++) { @@ -3327,7 +3402,7 @@ int CGlobalTRex::ixgbe_start(void){ 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); - assert(CGlobalInfo::m_mem_pool[socket_id].m_big_mbuf_pool); + assert(CGlobalInfo::m_mem_pool[socket_id].m_mbuf_pool_2048); /* drop queue */ @@ -3335,7 +3410,7 @@ int CGlobalTRex::ixgbe_start(void){ RTE_TEST_RX_DESC_DEFAULT, socket_id, &m_port_cfg.m_rx_conf, - CGlobalInfo::m_mem_pool[socket_id].m_big_mbuf_pool); + CGlobalInfo::m_mem_pool[socket_id].m_mbuf_pool_2048); /* set the filter queue */ @@ -3345,7 +3420,7 @@ int CGlobalTRex::ixgbe_start(void){ RTE_TEST_RX_LATENCY_DESC_DEFAULT, socket_id, &m_port_cfg.m_rx_conf, - CGlobalInfo::m_mem_pool[socket_id].m_big_mbuf_pool); + CGlobalInfo::m_mem_pool[socket_id].m_mbuf_pool_9k); int qid; for ( qid=0; qid<(m_max_queues_per_port+1); qid++) { @@ -4718,10 +4793,7 @@ int main_test(int argc , char * argv[]){ #if 0 printf(" test_send \n"); g_trex.test_send(); - // while (1) { - delay(10000); - exit(0); - // } + exit(1); #endif if ( CGlobalInfo::m_options.preview.getOnlyLatency() ){ diff --git a/src/platform_cfg.cpp b/src/platform_cfg.cpp index ca42aa31..15834544 100755 --- a/src/platform_cfg.cpp +++ b/src/platform_cfg.cpp @@ -35,9 +35,17 @@ void CPlatformMemoryYamlInfo::reset(){ m_mbuf[MBUF_64] = m_mbuf[MBUF_64]*2; m_mbuf[MBUF_2048] = CONST_NB_MBUF_2_10G/2; + m_mbuf[MBUF_4096] = 128; + m_mbuf[MBUF_9k] = 512; + + m_mbuf[TRAFFIC_MBUF_64] = m_mbuf[MBUF_64] * 4; m_mbuf[TRAFFIC_MBUF_2048] = CONST_NB_MBUF_2_10G * 8; + m_mbuf[TRAFFIC_MBUF_4096] = 128; + m_mbuf[TRAFFIC_MBUF_9k] = 512; + + m_mbuf[MBUF_DP_FLOWS] = (1024*1024/2); m_mbuf[MBUF_GLOBAL_FLOWS] =(10*1024/2); } @@ -47,7 +55,11 @@ const std::string names []={ "MBUF_256", "MBUF_512", "MBUF_1024", - "MBUF_2048", + "MBUF_2048", + "MBUF_4096", + "MBUF_9K", + + "TRAFFIC_MBUF_64", "TRAFFIC_MBUF_128", @@ -55,6 +67,9 @@ const std::string names []={ "TRAFFIC_MBUF_512", "TRAFFIC_MBUF_1024", "TRAFFIC_MBUF_2048", + "TRAFFIC_MBUF_4096", + "TRAFFIC_MBUF_9K", + "MBUF_DP_FLOWS", "MBUF_GLOBAL_FLOWS" @@ -214,6 +229,15 @@ void operator >> (const YAML::Node& node, CPlatformMemoryYamlInfo & plat_info) { node["mbuf_2048"] >> plat_info.m_mbuf[MBUF_2048]; } + if ( node.FindValue("mbuf_4096") ){ + node["mbuf_4096"] >> plat_info.m_mbuf[MBUF_4096]; + } + + if ( node.FindValue("mbuf_9k") ){ + node["mbuf_9k"] >> plat_info.m_mbuf[MBUF_9k]; + } + + if ( node.FindValue("traffic_mbuf_64") ){ node["traffic_mbuf_64"] >> plat_info.m_mbuf[TRAFFIC_MBUF_64]; } @@ -238,6 +262,15 @@ void operator >> (const YAML::Node& node, CPlatformMemoryYamlInfo & plat_info) { node["traffic_mbuf_2048"] >> plat_info.m_mbuf[TRAFFIC_MBUF_2048]; } + if ( node.FindValue("traffic_mbuf_4096") ){ + node["traffic_mbuf_4096"] >> plat_info.m_mbuf[TRAFFIC_MBUF_4096]; + } + + if ( node.FindValue("traffic_mbuf_9k") ){ + node["traffic_mbuf_9k"] >> plat_info.m_mbuf[TRAFFIC_MBUF_9k]; + } + + if ( node.FindValue("dp_flows") ){ node["dp_flows"] >> plat_info.m_mbuf[MBUF_DP_FLOWS]; } diff --git a/src/platform_cfg.h b/src/platform_cfg.h index 4fc3c3dd..e8f93d0b 100755 --- a/src/platform_cfg.h +++ b/src/platform_cfg.h @@ -31,25 +31,31 @@ limitations under the License. #define CONST_NB_MBUF_2_10G (16380/4) -typedef enum { MBUF_64 =0, // per dual port, per NUMA +typedef enum { MBUF_64 , // per dual port, per NUMA + + MBUF_128 , + MBUF_256 , + MBUF_512 , + MBUF_1024 , + MBUF_2048 , + MBUF_4096 , + MBUF_9k , - MBUF_128 =1, - MBUF_256 =2, - MBUF_512 =3, - MBUF_1024 =4, - MBUF_2048 =5, // per NUMA - TRAFFIC_MBUF_64 =6, - TRAFFIC_MBUF_128 =7, - TRAFFIC_MBUF_256 =8, - TRAFFIC_MBUF_512 =9, - TRAFFIC_MBUF_1024 =10, - TRAFFIC_MBUF_2048 =11, - - MBUF_DP_FLOWS =12, - MBUF_GLOBAL_FLOWS =13, - MBUF_SIZE =14 + TRAFFIC_MBUF_64 , + TRAFFIC_MBUF_128 , + TRAFFIC_MBUF_256 , + TRAFFIC_MBUF_512 , + TRAFFIC_MBUF_1024 , + TRAFFIC_MBUF_2048 , + TRAFFIC_MBUF_4096 , + TRAFFIC_MBUF_9k , + + + MBUF_DP_FLOWS , + MBUF_GLOBAL_FLOWS , + MBUF_SIZE } mbuf_sizes_t; const std::string * get_mbuf_names(void); diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index 51db0b20..95cd895b 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -175,6 +175,16 @@ TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, TrexStream stream->m_vm.add_instruction(new StreamVmInstructionFixChecksumIpv4(pkt_offset)); } + +void +TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexStream *stream, Json::Value &result){ + + std::string flow_var_name = parse_string(inst, "name", result); + + stream->m_vm.add_instruction(new StreamVmInstructionChangePktSize(flow_var_name)); +} + + void TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result){ @@ -255,7 +265,7 @@ TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, TrexStream *stream, Json::V for (int i = 0; i < instructions.size(); i++) { const Json::Value & inst = parse_object(instructions, i, result); - auto vm_types = {"fix_checksum_ipv4", "flow_var", "write_flow_var","tuple_flow_var"}; + auto vm_types = {"fix_checksum_ipv4", "flow_var", "write_flow_var","tuple_flow_var","trim_pkt_size"}; std::string vm_type = parse_choice(inst, "type", vm_types, result); // checksum instruction @@ -269,7 +279,10 @@ TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, TrexStream *stream, Json::V parse_vm_instr_write_flow_var(inst, stream, result); } else if (vm_type == "tuple_flow_var") { - parse_vm_instr_tuple_flow_var(inst, stream, result); + parse_vm_instr_tuple_flow_var(inst, stream, result); + + } else if (vm_type == "trim_pkt_size") { + parse_vm_instr_trim_pkt_size(inst, stream, result); } else { /* internal error */ throw TrexRpcException("internal error"); diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h index f4651d7b..b1750053 100644 --- a/src/rpc-server/commands/trex_rpc_cmds.h +++ b/src/rpc-server/commands/trex_rpc_cmds.h @@ -96,6 +96,8 @@ void parse_vm(const Json::Value &vm, TrexStream *stream, Json::Value &result); void parse_vm_instr_checksum(const Json::Value &inst, TrexStream *stream, Json::Value &result); void parse_vm_instr_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result); void parse_vm_instr_tuple_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result); +void parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexStream *stream, Json::Value &result); + void parse_vm_instr_write_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result); ); diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h index b4f19111..a164f266 100644 --- a/src/stateless/cp/trex_stream.h +++ b/src/stateless/cp/trex_stream.h @@ -32,6 +32,8 @@ limitations under the License. #include <trex_stream_vm.h> #include <stdio.h> #include <string.h> +#include <common/captureFile.h> + class TrexRpcCmdAddStream; @@ -123,8 +125,8 @@ public: virtual ~TrexStream(); /* defines the min max per packet supported */ - static const uint32_t MIN_PKT_SIZE_BYTES = 1; - static const uint32_t MAX_PKT_SIZE_BYTES = 9000; + static const uint32_t MIN_PKT_SIZE_BYTES = 60; + static const uint32_t MAX_PKT_SIZE_BYTES = MAX_PKT_SIZE; /* provides storage for the stream json*/ void store_stream_json(const Json::Value &stream_json); diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp index a3f585ad..b992d1ab 100644 --- a/src/stateless/cp/trex_stream_vm.cpp +++ b/src/stateless/cp/trex_stream_vm.cpp @@ -107,11 +107,14 @@ void StreamVmInstructionFlowMan::Dump(FILE *fd){ void StreamVmInstructionWriteToPkt::Dump(FILE *fd){ - fprintf(fd," write_pkt , %s ,%lu, add, %ld, big, %lu \n",m_flow_var_name.c_str(),(ulong)m_pkt_offset,(long)m_add_value,(ulong)(m_is_big_endian?1:0)); } +void StreamVmInstructionChangePktSize::Dump(FILE *fd){ + fprintf(fd," pkt_size_change , %s \n",m_flow_var_name.c_str() ); +} + void StreamVmInstructionFlowClient::Dump(FILE *fd){ @@ -192,6 +195,7 @@ void StreamVm::build_flow_var_table() { m_cur_var_offset=0; uint32_t ins_id=0; m_is_random_var=false; + m_is_change_pkt_size=false; /* scan all flow var instruction and build */ for (auto inst : m_inst_list) { @@ -201,6 +205,10 @@ void StreamVm::build_flow_var_table() { m_is_random_var =true; } } + + if ( inst->get_instruction_type() == StreamVmInstruction::itPKT_SIZE_CHANGE ){ + m_is_change_pkt_size=true; + } } /* if we found allocate BSS +4 bytes */ @@ -296,6 +304,51 @@ void StreamVm::build_flow_var_table() { ins_id++; } + + ins_id=0; + + /* second interation for sanity check and fixups*/ + for (auto inst : m_inst_list) { + + + if (inst->get_instruction_type() == StreamVmInstruction::itPKT_SIZE_CHANGE ) { + StreamVmInstructionChangePktSize *lpPkt =(StreamVmInstructionChangePktSize *)inst; + + VmFlowVarRec var; + if ( var_lookup(lpPkt->m_flow_var_name ,var) == false){ + + std::stringstream ss; + ss << "instruction id '" << ins_id << "' packet size with no valid flow varible name '" << lpPkt->m_flow_var_name << "'" ; + err(ss.str()); + } + + if ( var.m_size_bytes != 2 ) { + std::stringstream ss; + ss << "instruction id '" << ins_id << "' packet size change should point to a flow varible with size 2 "; + err(ss.str()); + } + + if ( var.m_ins.m_ins_flowv->m_max_value > m_pkt_size) { + var.m_ins.m_ins_flowv->m_max_value =m_pkt_size; + } + + if (var.m_ins.m_ins_flowv->m_min_value > m_pkt_size) { + var.m_ins.m_ins_flowv->m_min_value = m_pkt_size; + } + + + if ( var.m_ins.m_ins_flowv->m_min_value >= var.m_ins.m_ins_flowv->m_max_value ) { + std::stringstream ss; + ss << "instruction id '" << ins_id << "' min packet size " << var.m_ins.m_ins_flowv->m_min_value << " is bigger or eq to max packet size " << var.m_ins.m_ins_flowv->m_max_value; + err(ss.str()); + } + + if ( var.m_ins.m_ins_flowv->m_min_value < 60) { + var.m_ins.m_ins_flowv->m_min_value =60; + } + } + }/* for */ + } void StreamVm::alloc_bss(){ @@ -474,6 +527,8 @@ void StreamVm::build_program(){ ss << "instruction id '" << ins_id << "' packet write with packet_offset " << lpPkt->m_pkt_offset + var.m_size_bytes << " bigger than packet size "<< m_pkt_size; err(ss.str()); } + + add_field_cnt(lpPkt->m_pkt_offset + var.m_size_bytes); @@ -555,6 +610,32 @@ void StreamVm::build_program(){ } } + + if (ins_type == StreamVmInstruction::itPKT_SIZE_CHANGE ) { + StreamVmInstructionChangePktSize *lpPkt =(StreamVmInstructionChangePktSize *)inst; + + VmFlowVarRec var; + if ( var_lookup(lpPkt->m_flow_var_name ,var) == false){ + + std::stringstream ss; + ss << "instruction id '" << ins_id << "' packet size with no valid flow varible name '" << lpPkt->m_flow_var_name << "'" ; + err(ss.str()); + } + + if ( var.m_size_bytes != 2 ) { + std::stringstream ss; + ss << "instruction id '" << ins_id << "' packet size change should point to a flow varible with size 2 "; + err(ss.str()); + } + + uint8_t flow_offset = get_var_offset(lpPkt->m_flow_var_name); + + StreamDPOpPktSizeChange pkt_size_ch; + pkt_size_ch.m_op =StreamDPVmInstructions::itPKT_SIZE_CHANGE; + pkt_size_ch.m_flow_offset = flow_offset; + m_instructions.add_command(&pkt_size_ch,sizeof(pkt_size_ch)); + } + ins_id++; } } @@ -790,6 +871,8 @@ void StreamDPVmInstructions::Dump(FILE *fd){ StreamDPOpPktWr64 *lpw64; StreamDPOpClientsLimit *lp_client; StreamDPOpClientsUnLimit *lp_client_unlimited; + StreamDPOpPktSizeChange *lp_pkt_size_change; + while ( p < p_end) { @@ -901,6 +984,12 @@ void StreamDPVmInstructions::Dump(FILE *fd){ p+=sizeof(StreamDPOpClientsUnLimit); break; + case itPKT_SIZE_CHANGE : + lp_pkt_size_change =(StreamDPOpPktSizeChange *)p; + lp_pkt_size_change->dump(fd,"pkt_size_c"); + p+=sizeof(StreamDPOpPktSizeChange); + break; + default: assert(0); @@ -955,4 +1044,7 @@ void StreamDPOpClientsUnLimit::dump(FILE *fd,std::string opt){ fprintf(fd," %10s op:%lu, flow_offset: %lu (%x-%x) flags:%x \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset,m_min_ip,m_max_ip,m_flags); } +void StreamDPOpPktSizeChange::dump(FILE *fd,std::string opt){ + fprintf(fd," %10s op:%lu, flow_offset: %lu \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset); +} diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h index 891e5b51..edc4f730 100644 --- a/src/stateless/cp/trex_stream_vm.h +++ b/src/stateless/cp/trex_stream_vm.h @@ -396,6 +396,21 @@ public: } __attribute__((packed)); +struct StreamDPOpPktSizeChange { + uint8_t m_op; + uint8_t m_flow_offset; /* offset to the flow var */ + + inline void run(uint8_t * flow_var_base,uint16_t & new_size) { + uint16_t * p_flow_var = (uint16_t*)(flow_var_base+m_flow_offset); + new_size = (*p_flow_var); + } + + void dump(FILE *fd,std::string opt); + + +} __attribute__((packed)); ; + + /* datapath instructions */ class StreamDPVmInstructions { public: @@ -422,7 +437,9 @@ public: itPKT_WR32 , itPKT_WR64 , itCLIENT_VAR , - itCLIENT_VAR_UNLIMIT + itCLIENT_VAR_UNLIMIT , + itPKT_SIZE_CHANGE , + }; @@ -443,12 +460,20 @@ private: class StreamDPVmInstructionsRunner { public: + StreamDPVmInstructionsRunner(){ + m_new_pkt_size=0;; + } inline void run(uint32_t * per_thread_random, uint32_t program_size, uint8_t * program, /* program */ uint8_t * flow_var, /* flow var */ uint8_t * pkt); /* pkt */ + inline uint16_t get_new_pkt_size(){ + return (m_new_pkt_size); + } +private: + uint16_t m_new_pkt_size; }; @@ -456,7 +481,8 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, uint32_t program_size, uint8_t * program, /* program */ uint8_t * flow_var, /* flow var */ - uint8_t * pkt){ + uint8_t * pkt + ){ uint8_t * p=program; @@ -473,6 +499,8 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, StreamDPOpPktWr16 *lpw16; StreamDPOpPktWr32 *lpw32; StreamDPOpPktWr64 *lpw64; + StreamDPOpPktSizeChange *lpw_pkt_size; + StreamDPOpClientsLimit *lpcl; StreamDPOpClientsUnLimit *lpclu; } ua ; @@ -586,6 +614,13 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, ua.lpw64->wr(flow_var,pkt); p+=sizeof(StreamDPOpPktWr64); break; + + case StreamDPVmInstructions::itPKT_SIZE_CHANGE : + ua.lpw_pkt_size =(StreamDPOpPktSizeChange *)p; + ua.lpw_pkt_size->run(flow_var,m_new_pkt_size); + p+=sizeof(StreamDPOpPktSizeChange); + break; + default: assert(0); } @@ -607,7 +642,8 @@ public: itFIX_IPV4_CS = 4, itFLOW_MAN = 5, itPKT_WR = 6, - itFLOW_CLIENT = 7 + itFLOW_CLIENT = 7 , + itPKT_SIZE_CHANGE = 8 }; @@ -880,7 +916,7 @@ public: /** - * write flow var to packet + * write flow var to packet, hhaim * */ class StreamVmInstructionWriteToPkt : public StreamVmInstruction { @@ -925,6 +961,36 @@ public: }; + +/** + * change packet size, + * + */ +class StreamVmInstructionChangePktSize : public StreamVmInstruction { +public: + + StreamVmInstructionChangePktSize(const std::string &flow_var_name) : + + m_flow_var_name(flow_var_name) + {} + + virtual instruction_type_t get_instruction_type() const { + return ( StreamVmInstruction::itPKT_SIZE_CHANGE ); + } + + virtual void Dump(FILE *fd); + + virtual StreamVmInstruction * clone() { + return new StreamVmInstructionChangePktSize(m_flow_var_name); + } + +public: + + /* flow var name to write */ + std::string m_flow_var_name; +}; + + /** * describes a VM program for DP * @@ -939,6 +1005,7 @@ public: m_program_size=0; m_max_pkt_offset_change=0; m_prefix_size = 0; + m_is_pkt_size_var=false; } StreamVmDp( uint8_t * bss, @@ -946,7 +1013,8 @@ public: uint8_t * prog, uint16_t prog_size, uint16_t max_pkt_offset, - uint16_t prefix_size + uint16_t prefix_size, + bool a_is_pkt_size_var ){ if (bss) { @@ -972,6 +1040,7 @@ public: m_max_pkt_offset_change = max_pkt_offset; m_prefix_size = prefix_size; + m_is_pkt_size_var=a_is_pkt_size_var; } ~StreamVmDp(){ @@ -993,7 +1062,8 @@ public: m_program_ptr, m_program_size, m_max_pkt_offset_change, - m_prefix_size + m_prefix_size, + m_is_pkt_size_var ); assert(lp); return (lp); @@ -1035,6 +1105,14 @@ public: m_prefix_size = prefix_size; } + void set_pkt_size_is_var(bool pkt_size_var){ + m_is_pkt_size_var=pkt_size_var; + } + bool is_pkt_size_var(){ + return (m_is_pkt_size_var); + } + + private: uint8_t * m_bss_ptr; /* pointer to the data section */ uint8_t * m_program_ptr; /* pointer to the program */ @@ -1042,6 +1120,7 @@ private: uint16_t m_program_size; /* program size*/ uint16_t m_max_pkt_offset_change; uint16_t m_prefix_size; + bool m_is_pkt_size_var; }; @@ -1093,7 +1172,8 @@ public: get_dp_instruction_buffer()->get_program(), get_dp_instruction_buffer()->get_program_size(), get_max_packet_update_offset(), - get_prefix_size() + get_prefix_size(), + is_var_pkt_size() ); assert(lp); return (lp); @@ -1142,6 +1222,11 @@ public: return m_prefix_size; } + bool is_var_pkt_size(){ + return (m_is_change_pkt_size); + } + + bool is_compiled() { return m_is_compiled; } @@ -1197,6 +1282,7 @@ private: private: bool m_is_random_var; + bool m_is_change_pkt_size; bool m_is_compiled; uint16_t m_prefix_size; uint16_t m_pkt_size; diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp index 0a9a88ab..a80efc08 100644 --- a/src/stateless/dp/trex_stateless_dp_core.cpp +++ b/src/stateless/dp/trex_stateless_dp_core.cpp @@ -149,10 +149,34 @@ rte_mbuf_t * CGenNodeStateless::alloc_node_with_vm(){ m_vm_flow_var, (uint8_t*)p); + uint16_t pkt_new_size=runner.get_new_pkt_size(); + if ( likely( pkt_new_size == 0) ) { + /* no packet size change */ + rte_mbuf_t * m_const = get_const_mbuf(); + if ( m_const != NULL) { + utl_rte_pktmbuf_add_after(m,m_const); + } + return (m); + } + /* packet size change there are a few changes */ rte_mbuf_t * m_const = get_const_mbuf(); - if ( m_const != NULL) { - utl_rte_pktmbuf_add_after(m,m_const); + if ( (m_const == 0 ) || (pkt_new_size<=prefix_size) ) { + /* one mbuf , just trim it */ + m->data_len = pkt_new_size; + m->pkt_len = pkt_new_size; + return (m); + } + + rte_mbuf_t * mi= CGlobalInfo::pktmbuf_alloc_small(get_socket_id()); + assert(mi); + rte_pktmbuf_attach(mi,m_const); + utl_rte_pktmbuf_add_after2(m,mi); + + if ( pkt_new_size < m->pkt_len) { + /* need to trim it */ + mi->data_len = (pkt_new_size - prefix_size); + m->pkt_len = pkt_new_size; } return (m); } @@ -617,6 +641,12 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, } + if ( lpDpVm->is_pkt_size_var() ) { + // mark the node as varible size + node->set_var_pkt_size(); + } + + if (lpDpVm->get_prefix_size() > pkt_size ) { lpDpVm->set_prefix_size(pkt_size); } diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h index 70a66e6a..dfa4cc13 100644 --- a/src/stateless/dp/trex_stream_node.h +++ b/src/stateless/dp/trex_stream_node.h @@ -60,7 +60,9 @@ public: SL_NODE_FLAGS_DIR =1, //USED by master SL_NODE_FLAGS_MBUF_CACHE =2, //USED by master - SL_NODE_CONST_MBUF =4 + SL_NODE_CONST_MBUF =4, + + SL_NODE_VAR_PKT_SIZE =8 }; @@ -282,6 +284,14 @@ public: } } + inline void set_var_pkt_size(){ + m_flags |= SL_NODE_VAR_PKT_SIZE; + } + + inline bool is_var_pkt_size(){ + return ( ( m_flags &SL_NODE_VAR_PKT_SIZE )?true:false); + } + inline void set_const_mbuf(rte_mbuf_t * m){ m_cache_mbuf=(void *)m; m_flags |= SL_NODE_CONST_MBUF; |