summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2016-01-05 20:51:47 +0200
committerHanoh Haim <hhaim@cisco.com>2016-01-05 20:51:47 +0200
commit5f07d1062309eea31e47a6d9ab23bb1c94de5c83 (patch)
tree667326ce482b79d9626badb80d8562a9ecf7551b /src
parentc905d6b0845e79dbc5d5d37eee560d1dbc58b6ff (diff)
parentd6be4b0e8a2cd92b5e6c455532431897f76331fe (diff)
Merge branch 'random_pkt'
Diffstat (limited to 'src')
-rwxr-xr-xsrc/bp_sim.cpp46
-rwxr-xr-xsrc/bp_sim.h49
-rwxr-xr-xsrc/common/captureFile.h2
-rw-r--r--src/gtest/trex_stateless_gtest.cpp198
-rwxr-xr-xsrc/main_dpdk.cpp134
-rwxr-xr-xsrc/platform_cfg.cpp35
-rwxr-xr-xsrc/platform_cfg.h38
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp17
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h2
-rw-r--r--src/stateless/cp/trex_stream.h6
-rw-r--r--src/stateless/cp/trex_stream_vm.cpp94
-rw-r--r--src/stateless/cp/trex_stream_vm.h100
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp34
-rw-r--r--src/stateless/dp/trex_stream_node.h12
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;