1/*
2 Hanoch Haim
3 Cisco Systems, Inc.
4*/
5
6/*
7Copyright (c) 2015-2015 Cisco Systems, Inc.
8
9Licensed under the Apache License, Version 2.0 (the "License");
10you may not use this file except in compliance with the License.
11You may obtain a copy of the License at
12
13    http://www.apache.org/licenses/LICENSE-2.0
14
15Unless required by applicable law or agreed to in writing, software
16distributed under the License is distributed on an "AS IS" BASIS,
17WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18See the License for the specific language governing permissions and
19limitations under the License.
20*/
21
22#include "bp_sim.h"
23#include "flow_stat_parser.h"
24#include <common/gtest.h>
25#include <common/basic_utils.h>
26#include <trex_stateless.h>
27#include <trex_stateless_dp_core.h>
28#include <trex_stateless_messaging.h>
29#include <trex_streams_compiler.h>
30#include <trex_stream_node.h>
31#include <trex_stream.h>
32#include <trex_stateless_port.h>
33#include <trex_rpc_server_api.h>
34#include <iostream>
35#include <vector>
36#include <inttypes.h>
37
38
39
40
41class CPcapLoader {
42public:
43    CPcapLoader();
44    ~CPcapLoader();
45
46
47public:
48    bool load_pcap_file(std::string file,int pkt_id=0);
49    void update_ip_src(uint32_t ip_addr);
50    void clone_packet_into_stream(TrexStream * stream);
51    void dump_packet();
52
53public:
54    bool                    m_valid;
55    CCapPktRaw              m_raw;
56    CPacketIndication       m_pkt_indication;
57};
58
59CPcapLoader::~CPcapLoader(){
60}
61
62bool CPcapLoader::load_pcap_file(std::string cap_file,int pkt_id){
63    m_valid=false;
64    CPacketParser parser;
65
66    CCapReaderBase * lp=CCapReaderFactory::CreateReader((char *)cap_file.c_str(),0);
67
68    if (lp == 0) {
69        printf(" ERROR file %s does not exist or not supported \n",(char *)cap_file.c_str());
70        return false;
71    }
72
73    int cnt=0;
74    bool found =false;
75
76
77    while ( true ) {
78        /* read packet */
79        if ( lp->ReadPacket(&m_raw) ==false ){
80            break;
81        }
82        if (cnt==pkt_id) {
83            found = true;
84            break;
85        }
86        cnt++;
87    }
88    if ( found ){
89        if ( parser.ProcessPacket(&m_pkt_indication, &m_raw) ){
90            m_valid = true;
91        }
92    }
93
94    delete lp;
95    return (m_valid);
96}
97
98void CPcapLoader::update_ip_src(uint32_t ip_addr){
99
100    if ( m_pkt_indication.l3.m_ipv4 ) {
101        m_pkt_indication.l3.m_ipv4->setSourceIp(ip_addr);
102        m_pkt_indication.l3.m_ipv4->updateCheckSum();
103    }
104}
105
106void CPcapLoader::clone_packet_into_stream(TrexStream * stream){
107
108    uint16_t pkt_size=m_raw.getTotalLen();
109
110    uint8_t      *binary = new uint8_t[pkt_size];
111    memcpy(binary,m_raw.raw,pkt_size);
112    stream->m_pkt.binary = binary;
113    stream->m_pkt.len    = pkt_size;
114}
115
116
117
118
119CPcapLoader::CPcapLoader(){
120
121}
122
123void CPcapLoader::dump_packet(){
124    if (m_valid ) {
125        m_pkt_indication.Dump(stdout,1);
126    }else{
127        fprintf(stdout," no packets were found \n");
128    }
129}
130
131
132
133
134class basic_vm  : public testing::Test {
135    protected:
136     virtual void SetUp() {
137     }
138     virtual void TearDown() {
139     }
140   public:
141};
142
143
144TEST_F(basic_vm, cache_basic) {
145
146    CGenNodeStateless *node = new CGenNodeStateless();
147
148    node->cache_mbuf_array_init();
149    int i;
150    node->cache_mbuf_array_alloc(10);
151    for (i=0; i<10; i++) {
152        rte_mbuf_t * m =CGlobalInfo::pktmbuf_alloc_small(0);
153        m->data_off=i;
154        node->cache_mbuf_array_set(i,(rte_mbuf_t *) m);
155    }
156
157    for (i=0; i<10; i++) {
158      rte_mbuf_t * m =node->cache_mbuf_array_get_cur();
159      printf(" %d \n",m->data_off);
160    }
161
162    node->cache_mbuf_array_free();
163
164    delete node;
165}
166
167
168TEST_F(basic_vm, pkt_size) {
169
170    EXPECT_EQ(calc_writable_mbuf_size(36,62),62);
171    EXPECT_EQ(calc_writable_mbuf_size(63,62),62);
172    EXPECT_EQ(calc_writable_mbuf_size(45,65),65);
173    EXPECT_EQ(calc_writable_mbuf_size(66,65),65);
174    EXPECT_EQ(calc_writable_mbuf_size(62,128),128);
175    EXPECT_EQ(calc_writable_mbuf_size(62,252),63);
176    EXPECT_EQ(calc_writable_mbuf_size(121,252),122);
177    EXPECT_EQ(calc_writable_mbuf_size(253,252),254);
178    EXPECT_EQ(calc_writable_mbuf_size(250,252),252);
179    EXPECT_EQ(calc_writable_mbuf_size(184,252),185);
180}
181
182
183TEST_F(basic_vm, vm_rand_limit0) {
184
185    StreamVm vm;
186
187    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,100,0,200,0x1234) );
188
189    vm.Dump(stdout);
190}
191
192TEST_F(basic_vm, vm_rand_limit1) {
193
194    StreamVm vm;
195
196    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,100,0,200,0x1234) );
197    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
198                        );
199    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
200
201    vm.compile(128);
202
203
204    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
205
206    printf (" program size : %lu \n",(ulong)program_size);
207
208
209    vm.Dump(stdout);
210
211}
212
213TEST_F(basic_vm, vm_rand_limit2) {
214
215    StreamVm vm;
216
217    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,100,0,100,0x1234) );
218    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var2",2,100,0,100,0x1234) );
219    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var3",4,100,0,100,0x1234) );
220    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var4",8,100,0,100,0x1234) );
221    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
222                        );
223    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
224
225    vm.compile(128);
226
227
228    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
229
230    printf (" program size : %lu \n",(ulong)program_size);
231
232
233    vm.Dump(stdout);
234
235}
236
237
238
239
240/* start/stop/stop back to back */
241TEST_F(basic_vm, vm0) {
242
243    StreamVm vm;
244
245    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(20) );
246    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",8,
247                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,1,1,7 )
248                        );
249    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",14, 0,true)
250                        );
251
252    vm.Dump(stdout);
253}
254
255TEST_F(basic_vm, vm1) {
256
257    StreamVm vm;
258
259    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1,
260                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,1,1,7 )
261                        );
262    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
263                        );
264    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
265
266    vm.compile(128);
267
268
269    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
270
271    printf (" program size : %lu \n",(ulong)program_size);
272
273
274    vm.Dump(stdout);
275
276}
277
278TEST_F(basic_vm, vm2) {
279
280    StreamVm vm;
281
282    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1,
283                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 )
284                        );
285    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
286                        );
287    //vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
288
289    vm.compile(128);
290
291
292    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
293
294    printf (" program size : %lu \n",(ulong)program_size);
295
296
297    vm.Dump(stdout);
298
299    uint8_t test_udp_pkt[14+20+4+4]={
300        0x00,0x00,0x00,0x01,0x00,0x00,
301        0x00,0x00,0x00,0x01,0x00,0x00,
302        0x08,0x00,
303
304        0x45,0x00,0x00,0x81, /*14 */
305        0xaf,0x7e,0x00,0x00, /*18 */
306        0x12,0x11,0xd9,0x23, /*22 */
307        0x01,0x01,0x01,0x01, /*26 */
308        0x3d,0xad,0x72,0x1b, /*30 */
309
310        0x11,0x11,
311        0x11,0x11,
312
313        0x00,0x6d,
314        0x00,0x00,
315    };
316
317
318
319    StreamDPVmInstructionsRunner runner;
320
321    uint8_t ex[]={5,
322                 6,
323                 7,
324                 1,
325                 2,
326                 3,
327                 4,
328                 5,
329                 6,
330                 7,
331                 1,
332                 2,
333                 3,
334                 4,
335                 5,
336                 6,
337                 7,
338                 1,
339                 2,
340                 3};
341
342    uint32_t random_per_thread=0;
343    int i;
344    for (i=0; i<20; i++) {
345        runner.run(&random_per_thread,
346                   program_size,
347                   vm.get_dp_instruction_buffer()->get_program(),
348                   vm.get_bss_ptr(),
349                   test_udp_pkt);
350        EXPECT_EQ(test_udp_pkt[26],ex[i]);
351    }
352
353}
354
355
356TEST_F(basic_vm, vm3) {
357
358    StreamVm vm;
359
360    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
361                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 )
362                        );
363    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
364                        );
365    //vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
366
367    vm.compile(128);
368
369
370    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
371
372    printf (" program size : %lu \n",(ulong)program_size);
373
374
375    vm.Dump(stdout);
376
377    #define PKT_TEST_SIZE (14+20+4+4)
378    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
379        0x00,0x00,0x00,0x01,0x00,0x00,
380        0x00,0x00,0x00,0x01,0x00,0x00,
381        0x08,0x00,
382
383        0x45,0x00,0x00,0x81, /*14 */
384        0xaf,0x7e,0x00,0x00, /*18 */
385        0x12,0x11,0xd9,0x23, /*22 */
386        0x01,0x01,0x01,0x01, /*26 */
387        0x3d,0xad,0x72,0x1b, /*30 */
388
389        0x11,0x11,
390        0x11,0x11,
391
392        0x00,0x6d,
393        0x00,0x00,
394    };
395
396
397
398    StreamDPVmInstructionsRunner runner;
399
400    uint8_t ex[]={5,
401                 6,
402                 7,
403                 1,
404                 2,
405                 3,
406                 4,
407                 5,
408                 6,
409                 7,
410                 1,
411                 2,
412                 3,
413                 4,
414                 5,
415                 6,
416                 7,
417                 1,
418                 2,
419                 3};
420
421    uint32_t random_per_thread=0;
422
423    int i;
424    for (i=0; i<20; i++) {
425        runner.run(&random_per_thread,
426                   program_size,
427                   vm.get_dp_instruction_buffer()->get_program(),
428                   vm.get_bss_ptr(),
429                   test_udp_pkt);
430
431        fprintf(stdout," %d \n",i);
432        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
433        /* big */
434        EXPECT_EQ(test_udp_pkt[29],ex[i]);
435        EXPECT_EQ(test_udp_pkt[28],0);
436        EXPECT_EQ(test_udp_pkt[27],0);
437        EXPECT_EQ(test_udp_pkt[26],0);
438    }
439
440}
441
442TEST_F(basic_vm, vm4) {
443
444    StreamVm vm;
445
446    vm.add_instruction( new StreamVmInstructionFlowMan( "var1", 8 /* size */,
447                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 )
448                        );
449    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,false)
450                        );
451    //vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
452
453    vm.compile(128);
454
455
456    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
457
458    printf (" program size : %lu \n",(ulong)program_size);
459
460
461    vm.Dump(stdout);
462
463    #define PKT_TEST_SIZE (14+20+4+4)
464    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
465        0x00,0x00,0x00,0x01,0x00,0x00,
466        0x00,0x00,0x00,0x01,0x00,0x00,
467        0x08,0x00,
468
469        0x45,0x00,0x00,0x81, /*14 */
470        0xaf,0x7e,0x00,0x00, /*18 */
471        0x12,0x11,0xd9,0x23, /*22 */
472        0x01,0x01,0x01,0x01, /*26 */
473        0x3d,0xad,0x72,0x1b, /*30 */
474
475        0x11,0x11,
476        0x11,0x11,
477
478        0x00,0x6d,
479        0x00,0x00,
480    };
481
482
483
484    StreamDPVmInstructionsRunner runner;
485
486    uint8_t ex[]={5,
487                 6,
488                 7,
489                 1,
490                 2,
491                 3,
492                 4,
493                 5,
494                 6,
495                 7,
496                 1,
497                 2,
498                 3,
499                 4,
500                 5,
501                 6,
502                 7,
503                 1,
504                 2,
505                 3};
506
507    uint32_t random_per_thread=0;
508
509    int i;
510    for (i=0; i<20; i++) {
511        runner.run(&random_per_thread,
512                   program_size,
513                   vm.get_dp_instruction_buffer()->get_program(),
514                   vm.get_bss_ptr(),
515                   test_udp_pkt);
516
517        fprintf(stdout," %d \n",i);
518        utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
519        /* not big */
520        EXPECT_EQ(test_udp_pkt[33],0);
521        EXPECT_EQ(test_udp_pkt[32],0);
522        EXPECT_EQ(test_udp_pkt[31],0);
523        EXPECT_EQ(test_udp_pkt[30],0);
524        EXPECT_EQ(test_udp_pkt[29],0);
525        EXPECT_EQ(test_udp_pkt[28],0);
526        EXPECT_EQ(test_udp_pkt[27],0);
527        EXPECT_EQ(test_udp_pkt[26],ex[i]);
528    }
529
530}
531
532
533/* two fields */
534TEST_F(basic_vm, vm5) {
535
536    StreamVm vm;
537
538    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
539                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 )
540                        );
541
542    vm.add_instruction( new StreamVmInstructionFlowMan( "var2",1 /* size */,
543                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC,24,23,27 ) );
544
545    /* src ip */
546    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
547                        );
548
549    /* change TOS */
550    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var2",15, 0,true)
551                        );
552
553    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
554
555    vm.compile(128);
556
557
558    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
559
560    printf (" program size : %lu \n",(ulong)program_size);
561
562
563    vm.Dump(stdout);
564
565    #define PKT_TEST_SIZE (14+20+4+4)
566    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
567        0x00,0x00,0x00,0x01,0x00,0x00,
568        0x00,0x00,0x00,0x01,0x00,0x00,
569        0x08,0x00,
570
571        0x45,0x00,0x00,0x81, /*14 */
572        0xaf,0x7e,0x00,0x00, /*18 */
573        0x12,0x11,0xd9,0x23, /*22 */
574        0x01,0x01,0x01,0x01, /*26 */
575        0x3d,0xad,0x72,0x1b, /*30 */
576
577        0x11,0x11,           /*34 */
578        0x11,0x11,
579
580        0x00,0x6d,
581        0x00,0x00,
582    };
583
584
585
586    StreamDPVmInstructionsRunner runner;
587
588    uint8_t ex[]={5,
589                 6,
590                 7,
591                 1,
592                 2,
593                 3,
594                 4,
595                 5,
596                 6,
597                 7,
598                 1,
599                 2,
600                 3,
601                 4,
602                 5,
603                 6,
604                 7,
605                 1,
606                 2,
607                 3};
608
609         uint8_t ex_tos[]={0x18,
610                      0x17,
611                      0x1b,
612                      0x1a,
613                      0x19,
614                      0x18,
615                      0x17,
616                      0x1b,
617                     0x1a,
618                     0x19,
619                     0x18,
620                     0x17,
621             0x1b,
622            0x1a,
623            0x19,
624            0x18,
625            0x17,
626             0x1b,
627            0x1a,
628            0x19,
629            0x18,
630            0x17,
631
632             0x1b,
633            0x1a,
634            0x19,
635            0x18,
636            0x17,
637
638             0x1b,
639            0x1a,
640            0x19,
641            0x18,
642            0x17,
643
644             0x1b,
645            0x1a,
646            0x19,
647            0x18,
648            0x17,
649         };
650
651    uint32_t random_per_thread=0;
652
653    int i;
654    for (i=0; i<20; i++) {
655        runner.run(&random_per_thread,
656                   program_size,
657                   vm.get_dp_instruction_buffer()->get_program(),
658                   vm.get_bss_ptr(),
659                   test_udp_pkt);
660
661        fprintf(stdout," %d \n",i);
662        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
663        /* not big */
664        EXPECT_EQ(test_udp_pkt[29],ex[i]);
665        EXPECT_EQ(test_udp_pkt[28],0);
666        EXPECT_EQ(test_udp_pkt[27],0);
667        EXPECT_EQ(test_udp_pkt[26],0);
668
669        /* check tos */
670        EXPECT_EQ(test_udp_pkt[15],ex_tos[i]);
671    }
672}
673
674
675TEST_F(basic_vm, vm_rand_len) {
676
677    StreamVm vm;
678
679    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,10,0,255,0x1234) );
680
681
682    /* change TOS */
683    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",15, 0,true));
684
685
686    vm.compile(128);
687
688
689    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
690
691    printf (" program size : %lu \n",(ulong)program_size);
692
693
694    vm.Dump(stdout);
695
696    #define PKT_TEST_SIZE (14+20+4+4)
697    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
698        0x00,0x00,0x00,0x01,0x00,0x00,
699        0x00,0x00,0x00,0x01,0x00,0x00,
700        0x08,0x00,
701
702        0x45,0x00,0x00,0x81, /*14 */
703        0xaf,0x7e,0x00,0x00, /*18 */
704        0x12,0x11,0xd9,0x23, /*22 */
705        0x01,0x01,0x01,0x01, /*26 */
706        0x3d,0xad,0x72,0x1b, /*30 */
707
708        0x11,0x11,           /*34 */
709        0x11,0x11,
710
711        0x00,0x6d,
712        0x00,0x00,
713    };
714
715
716
717    StreamDPVmInstructionsRunner runner;
718
719         uint8_t ex_tos[]={
720             0x98,
721             0xbd,
722             0xb5,
723             0x7 ,
724             0x14,
725             0xd6,
726             0x3 ,
727             0x90,
728             0x5d,
729             0x88,
730              0x98,
731              0xbd,
732              0xb5,
733              0x7 ,
734              0x14,
735              0xd6,
736              0x3 ,
737              0x90,
738              0x5d,
739              0x88
740         };
741
742
743    uint32_t random_per_thread=0;
744
745    int i;
746    for (i=0; i<20; i++) {
747        runner.run(&random_per_thread,
748                   program_size,
749                   vm.get_dp_instruction_buffer()->get_program(),
750                   vm.get_bss_ptr(),
751                   test_udp_pkt);
752
753        fprintf(stdout," %d :",i);
754        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
755        /* not big */
756        printf(" %x \n",test_udp_pkt[15]);
757
758        /* check tos */
759        EXPECT_EQ(test_udp_pkt[15],ex_tos[i]);
760    }
761}
762
763TEST_F(basic_vm, vm_rand_len_l0) {
764
765    StreamVm vm;
766
767    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",1,10,1,10,0x1234) );
768
769
770    /* change TOS */
771    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",15, 0,true));
772
773
774    vm.compile(128);
775
776
777    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
778
779    printf (" program size : %lu \n",(ulong)program_size);
780
781
782    vm.Dump(stdout);
783
784    #define PKT_TEST_SIZE (14+20+4+4)
785    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
786        0x00,0x00,0x00,0x01,0x00,0x00,
787        0x00,0x00,0x00,0x01,0x00,0x00,
788        0x08,0x00,
789
790        0x45,0x00,0x00,0x81, /*14 */
791        0xaf,0x7e,0x00,0x00, /*18 */
792        0x12,0x11,0xd9,0x23, /*22 */
793        0x01,0x01,0x01,0x01, /*26 */
794        0x3d,0xad,0x72,0x1b, /*30 */
795
796        0x11,0x11,           /*34 */
797        0x11,0x11,
798
799        0x00,0x6d,
800        0x00,0x00,
801    };
802
803
804
805    StreamDPVmInstructionsRunner runner;
806
807         uint8_t ex_tos[]={
808         0x7,
809         0xa,
810         0xa,
811         0x4,
812         0x7,
813         0x5,
814         0x2,
815         0x3,
816         0x8,
817         0x9,
818          0x7,
819          0xa,
820          0xa,
821          0x4,
822          0x7,
823          0x5,
824          0x2,
825          0x3,
826          0x8,
827          0x9,
828
829         };
830
831
832    uint32_t random_per_thread=0;
833
834    int i;
835    for (i=0; i<20; i++) {
836        runner.run(&random_per_thread,
837                   program_size,
838                   vm.get_dp_instruction_buffer()->get_program(),
839                   vm.get_bss_ptr(),
840                   test_udp_pkt);
841
842        fprintf(stdout," %d :",i);
843        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
844        /* not big */
845        printf(" %x \n",test_udp_pkt[15]);
846
847        /* check tos */
848        EXPECT_EQ(test_udp_pkt[15],ex_tos[i]);
849    }
850}
851
852
853TEST_F(basic_vm, vm_rand_len1) {
854
855    StreamVm vm;
856
857    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",2,10,0,((1<<16)-1),0x1234) );
858
859
860    /* change TOS */
861    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",15, 0,true));
862
863
864    vm.compile(128);
865
866
867    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
868
869    printf (" program size : %lu \n",(ulong)program_size);
870
871
872    vm.Dump(stdout);
873
874    #define PKT_TEST_SIZE (14+20+4+4)
875    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
876        0x00,0x00,0x00,0x01,0x00,0x00,
877        0x00,0x00,0x00,0x01,0x00,0x00,
878        0x08,0x00,
879
880        0x45,0x00,0x00,0x81, /*14 */
881        0xaf,0x7e,0x00,0x00, /*18 */
882        0x12,0x11,0xd9,0x23, /*22 */
883        0x01,0x01,0x01,0x01, /*26 */
884        0x3d,0xad,0x72,0x1b, /*30 */
885
886        0x11,0x11,           /*34 */
887        0x11,0x11,
888
889        0x00,0x6d,
890        0x00,0x00,
891    };
892
893
894
895    StreamDPVmInstructionsRunner runner;
896
897
898         uint16_t ex_tos[]={
899             0x983b,
900             0xbd64,
901             0xb512,
902             0x715 ,
903             0x1410,
904             0xd664,
905             0x371 ,
906             0x9058,
907             0x5d3b,
908             0x884d,
909             0x983b,
910             0xbd64,
911             0xb512,
912             0x715 ,
913             0x1410,
914             0xd664,
915             0x371 ,
916             0x9058,
917             0x5d3b,
918             0x884d
919         };
920
921
922    uint32_t random_per_thread=0;
923
924    int i;
925    for (i=0; i<20; i++) {
926        runner.run(&random_per_thread,
927                   program_size,
928                   vm.get_dp_instruction_buffer()->get_program(),
929                   vm.get_bss_ptr(),
930                   test_udp_pkt);
931
932        fprintf(stdout," %d :",i);
933        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
934        /* not big */
935        printf(" %x \n",*((uint16_t*)&test_udp_pkt[15]));
936
937        /* check tos */
938        EXPECT_EQ(*((uint16_t*)&test_udp_pkt[15]),ex_tos[i]);
939    }
940}
941
942TEST_F(basic_vm, vm_rand_len2) {
943
944    StreamVm vm;
945
946    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",4,10,0,((1UL<<32)-1),0x1234) );
947
948
949    /* change TOS */
950    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",15, 0,true));
951
952
953    vm.compile(128);
954
955
956    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
957
958    printf (" program size : %lu \n",(ulong)program_size);
959
960
961    vm.Dump(stdout);
962
963    #define PKT_TEST_SIZE (14+20+4+4)
964    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
965        0x00,0x00,0x00,0x01,0x00,0x00,
966        0x00,0x00,0x00,0x01,0x00,0x00,
967        0x08,0x00,
968
969        0x45,0x00,0x00,0x81, /*14 */
970        0xaf,0x7e,0x00,0x00, /*18 */
971        0x12,0x11,0xd9,0x23, /*22 */
972        0x01,0x01,0x01,0x01, /*26 */
973        0x3d,0xad,0x72,0x1b, /*30 */
974
975        0x11,0x11,           /*34 */
976        0x11,0x11,
977
978        0x00,0x6d,
979        0x00,0x00,
980    };
981
982
983
984    StreamDPVmInstructionsRunner runner;
985
986         uint32_t ex_tos[]={
987             0xbd64983b,
988             0x715b512 ,
989             0xd6641410,
990             0x90580371,
991             0x884d5d3b,
992             0x8e0f8212,
993             0xf00b2f39,
994             0xa015ee4e,
995             0x540b390e,
996             0xdb778538,
997             0xbd64983b,
998             0x715b512 ,
999             0xd6641410,
1000             0x90580371,
1001             0x884d5d3b,
1002             0x8e0f8212,
1003             0xf00b2f39,
1004             0xa015ee4e,
1005             0x540b390e,
1006             0xdb778538
1007         };
1008
1009
1010    uint32_t random_per_thread=0;
1011
1012    int i;
1013    for (i=0; i<20; i++) {
1014        runner.run(&random_per_thread,
1015                   program_size,
1016                   vm.get_dp_instruction_buffer()->get_program(),
1017                   vm.get_bss_ptr(),
1018                   test_udp_pkt);
1019
1020        fprintf(stdout," %d :",i);
1021        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
1022        /* not big */
1023        printf(" %x \n",*((uint32_t*)&test_udp_pkt[15]));
1024
1025        /* check tos */
1026        EXPECT_EQ(*((uint32_t*)&test_udp_pkt[15]),ex_tos[i]);
1027    }
1028}
1029
1030TEST_F(basic_vm, vm_rand_len3) {
1031
1032    StreamVm vm;
1033
1034    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",8,10,0,UINT64_MAX,0x1234) );
1035
1036
1037    /* change TOS */
1038    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",15, 0,true));
1039
1040
1041    vm.compile(128);
1042
1043
1044    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1045
1046    printf (" program size : %lu \n",(ulong)program_size);
1047
1048
1049    vm.Dump(stdout);
1050
1051    #define PKT_TEST_SIZE (14+20+4+4)
1052    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
1053        0x00,0x00,0x00,0x01,0x00,0x00,
1054        0x00,0x00,0x00,0x01,0x00,0x00,
1055        0x08,0x00,
1056
1057        0x45,0x00,0x00,0x81, /*14 */
1058        0xaf,0x7e,0x00,0x00, /*18 */
1059        0x12,0x11,0xd9,0x23, /*22 */
1060        0x01,0x01,0x01,0x01, /*26 */
1061        0x3d,0xad,0x72,0x1b, /*30 */
1062
1063        0x11,0x11,           /*34 */
1064        0x11,0x11,
1065
1066        0x00,0x6d,
1067        0x00,0x00,
1068    };
1069
1070
1071
1072    StreamDPVmInstructionsRunner runner;
1073
1074#if 0
1075         uint32_t ex_tos[]={
1076             0xbd64983b,
1077             0x715b512 ,
1078             0xd6641410,
1079             0x90580371,
1080             0x884d5d3b,
1081             0x8e0f8212,
1082             0xf00b2f39,
1083             0xa015ee4e,
1084             0x540b390e,
1085             0xdb778538,
1086             0xbd64983b,
1087             0x715b512 ,
1088             0xd6641410,
1089             0x90580371,
1090             0x884d5d3b,
1091             0x8e0f8212,
1092             0xf00b2f39,
1093             0xa015ee4e,
1094             0x540b390e,
1095             0xdb778538
1096         };
1097#endif
1098
1099
1100    uint32_t random_per_thread=0;
1101
1102    int i;
1103    for (i=0; i<20; i++) {
1104        runner.run(&random_per_thread,
1105                   program_size,
1106                   vm.get_dp_instruction_buffer()->get_program(),
1107                   vm.get_bss_ptr(),
1108                   test_udp_pkt);
1109
1110        fprintf(stdout," %d :",i);
1111        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
1112        /* not big */
1113        printf(" %" PRIx64 " \n",*((uint64_t*)&test_udp_pkt[15]));
1114
1115        /* check tos */
1116        //EXPECT_EQ(*((uint64_t*)&test_udp_pkt[15]),ex_tos[i]);
1117    }
1118}
1119
1120
1121TEST_F(basic_vm, vm_rand_len3_l0) {
1122
1123    StreamVm vm;
1124
1125    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",8,10,0x1234567,0x2234567,0x1234) );
1126
1127
1128    /* change TOS */
1129    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",15, 0,true));
1130
1131
1132    vm.compile(128);
1133
1134
1135    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1136
1137    printf (" program size : %lu \n",(ulong)program_size);
1138
1139
1140    vm.Dump(stdout);
1141
1142    #define PKT_TEST_SIZE (14+20+4+4)
1143    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
1144        0x00,0x00,0x00,0x01,0x00,0x00,
1145        0x00,0x00,0x00,0x01,0x00,0x00,
1146        0x08,0x00,
1147
1148        0x45,0x00,0x00,0x81, /*14 */
1149        0xaf,0x7e,0x00,0x00, /*18 */
1150        0x12,0x11,0xd9,0x23, /*22 */
1151        0x01,0x01,0x01,0x01, /*26 */
1152        0x3d,0xad,0x72,0x1b, /*30 */
1153
1154        0x11,0x11,           /*34 */
1155        0x11,0x11,
1156
1157        0x00,0x6d,
1158        0x00,0x00,
1159    };
1160
1161
1162
1163    StreamDPVmInstructionsRunner runner;
1164
1165#if 0
1166         uint32_t ex_tos[]={
1167             0xbd64983b,
1168             0x715b512 ,
1169             0xd6641410,
1170             0x90580371,
1171             0x884d5d3b,
1172             0x8e0f8212,
1173             0xf00b2f39,
1174             0xa015ee4e,
1175             0x540b390e,
1176             0xdb778538,
1177             0xbd64983b,
1178             0x715b512 ,
1179             0xd6641410,
1180             0x90580371,
1181             0x884d5d3b,
1182             0x8e0f8212,
1183             0xf00b2f39,
1184             0xa015ee4e,
1185             0x540b390e,
1186             0xdb778538
1187         };
1188#endif
1189
1190
1191    uint32_t random_per_thread=0;
1192
1193    int i;
1194    for (i=0; i<20; i++) {
1195        runner.run(&random_per_thread,
1196                   program_size,
1197                   vm.get_dp_instruction_buffer()->get_program(),
1198                   vm.get_bss_ptr(),
1199                   test_udp_pkt);
1200
1201        fprintf(stdout," %d :",i);
1202        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
1203        /* not big */
1204        printf(" %" PRIx64 " \n",pal_ntohl64(*((uint64_t*)&test_udp_pkt[15])));
1205
1206        /* check tos */
1207        //EXPECT_EQ(*((uint64_t*)&test_udp_pkt[15]),ex_tos[i]);
1208    }
1209}
1210
1211
1212/* -load file, write to file  */
1213TEST_F(basic_vm, vm6) {
1214
1215
1216
1217    StreamVm vm;
1218
1219    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
1220                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0x10000001,0x10000001,0x100000fe)
1221                        );
1222
1223    vm.add_instruction( new StreamVmInstructionFlowMan( "var2",1 /* size */,
1224                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC,24,23,27 ) );
1225
1226    /* src ip */
1227    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
1228                        );
1229
1230    /* change TOS */
1231    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var2",15, 0,true)
1232                        );
1233
1234    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
1235
1236    vm.compile(128);
1237
1238
1239    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1240
1241    printf (" program size : %lu \n",(ulong)program_size);
1242
1243
1244    vm.Dump(stdout);
1245
1246    CPcapLoader pcap;
1247    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1248
1249
1250
1251    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm6.pcap");
1252    assert(lpWriter);
1253
1254
1255    StreamDPVmInstructionsRunner runner;
1256
1257    uint32_t random_per_thread=0;
1258
1259    int i;
1260    for (i=0; i<20; i++) {
1261        runner.run(&random_per_thread,
1262                   program_size,
1263                   vm.get_dp_instruction_buffer()->get_program(),
1264                   vm.get_bss_ptr(),
1265                   (uint8_t*)pcap.m_raw.raw);
1266
1267        //utl_DumpBuffer(stdout,pcap.m_raw.raw,pcap.m_raw.pkt_len,0);
1268        assert(lpWriter->write_packet(&pcap.m_raw));
1269    }
1270
1271    delete lpWriter;
1272
1273    CErfCmp cmp;
1274
1275    bool res1=cmp.compare("exp/udp_64B_vm6.pcap","exp/udp_64B_vm6-ex.pcap");
1276    EXPECT_EQ(1, res1?1:0);
1277}
1278
1279
1280TEST_F(basic_vm, vm_rand_len3_l1) {
1281
1282    StreamVm vm;
1283
1284    vm.add_instruction( new StreamVmInstructionFlowRandLimit( "var1",4,10,0x01234567,0x02234567,0x1234) );
1285
1286
1287    /* change TOS */
1288    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",15, 0,true));
1289
1290
1291    vm.compile(128);
1292
1293
1294    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1295
1296    printf (" program size : %lu \n",(ulong)program_size);
1297
1298
1299    vm.Dump(stdout);
1300
1301    #define PKT_TEST_SIZE (14+20+4+4)
1302    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
1303        0x00,0x00,0x00,0x01,0x00,0x00,
1304        0x00,0x00,0x00,0x01,0x00,0x00,
1305        0x08,0x00,
1306
1307        0x45,0x00,0x00,0x81, /*14 */
1308        0xaf,0x7e,0x00,0x00, /*18 */
1309        0x12,0x11,0xd9,0x23, /*22 */
1310        0x01,0x01,0x01,0x01, /*26 */
1311        0x3d,0xad,0x72,0x1b, /*30 */
1312
1313        0x11,0x11,           /*34 */
1314        0x11,0x11,
1315
1316        0x00,0x6d,
1317        0x00,0x00,
1318    };
1319
1320
1321
1322    StreamDPVmInstructionsRunner runner;
1323
1324#if 0
1325         uint32_t ex_tos[]={
1326             0xbd64983b,
1327             0x715b512 ,
1328             0xd6641410,
1329             0x90580371,
1330             0x884d5d3b,
1331             0x8e0f8212,
1332             0xf00b2f39,
1333             0xa015ee4e,
1334             0x540b390e,
1335             0xdb778538,
1336             0xbd64983b,
1337             0x715b512 ,
1338             0xd6641410,
1339             0x90580371,
1340             0x884d5d3b,
1341             0x8e0f8212,
1342             0xf00b2f39,
1343             0xa015ee4e,
1344             0x540b390e,
1345             0xdb778538
1346         };
1347#endif
1348
1349
1350    uint32_t random_per_thread=0;
1351
1352    int i;
1353    for (i=0; i<20; i++) {
1354        runner.run(&random_per_thread,
1355                   program_size,
1356                   vm.get_dp_instruction_buffer()->get_program(),
1357                   vm.get_bss_ptr(),
1358                   test_udp_pkt);
1359
1360        fprintf(stdout," %d :",i);
1361        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
1362        /* not big */
1363        printf(" %x \n",PAL_NTOHL(*((uint64_t*)&test_udp_pkt[15])));
1364
1365        /* check tos */
1366        //EXPECT_EQ(*((uint64_t*)&test_udp_pkt[15]),ex_tos[i]);
1367    }
1368}
1369
1370
1371/* test client command */
1372TEST_F(basic_vm, vm7) {
1373
1374
1375
1376    StreamVm vm;
1377
1378    vm.add_instruction( new StreamVmInstructionFlowClient( "cl1",
1379                                                           0x10000001,
1380                                                           0x10000004,
1381                                                           1025,
1382                                                           1027,
1383                                                           100,
1384                                                           0) );
1385
1386    /* src ip */
1387    vm.add_instruction( new StreamVmInstructionWriteToPkt( "cl1.ip",26, 0,true)
1388                        );
1389
1390    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
1391
1392    /* src port */
1393    vm.add_instruction( new StreamVmInstructionWriteToPkt( "cl1.port",34, 0,true)
1394                        );
1395
1396    vm.compile(128);
1397
1398
1399    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1400
1401    printf (" program size : %lu \n",(ulong)program_size);
1402
1403
1404    vm.Dump(stdout);
1405
1406    CPcapLoader pcap;
1407    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1408
1409
1410
1411    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm7.pcap");
1412    assert(lpWriter);
1413
1414
1415    StreamDPVmInstructionsRunner runner;
1416
1417    uint32_t random_per_thread=0;
1418
1419    int i;
1420    for (i=0; i<20; i++) {
1421        runner.run(&random_per_thread,
1422                   program_size,
1423                   vm.get_dp_instruction_buffer()->get_program(),
1424                   vm.get_bss_ptr(),
1425                   (uint8_t*)pcap.m_raw.raw);
1426
1427        assert(lpWriter->write_packet(&pcap.m_raw));
1428    }
1429
1430    delete lpWriter;
1431
1432    CErfCmp cmp;
1433
1434    bool res1=cmp.compare("exp/udp_64B_vm7.pcap","exp/udp_64B_vm7-ex.pcap");
1435    EXPECT_EQ(1, res1?1:0);
1436}
1437
1438
1439////////////////////////////////////////////////////////
1440
1441TEST_F(basic_vm, vm_mask_err) {
1442
1443    bool fail=false;
1444    /* should fail */
1445
1446    try {
1447        StreamVm vm;
1448        vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
1449        vm.compile(128);
1450        uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1451        printf(" program_size : %lu \n",(ulong)program_size);
1452     } catch (const TrexException &ex) {
1453        fail=true;
1454    }
1455
1456     EXPECT_EQ(true, fail);
1457}
1458
1459
1460TEST_F(basic_vm, vm_mask1) {
1461
1462
1463
1464    StreamVm vm;
1465
1466    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
1467                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0x10000007,0x10000007,0x100000fe)  );
1468
1469
1470    vm.add_instruction( new StreamVmInstructionWriteMaskToPkt("var1", 36,2,0x00ff,0,0,1) );
1471
1472    vm.compile(128);
1473
1474
1475    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1476
1477    printf (" program size : %lu \n",(ulong)program_size);
1478
1479
1480    vm.Dump(stdout);
1481
1482    CPcapLoader pcap;
1483    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1484
1485
1486    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask1.pcap");
1487    assert(lpWriter);
1488
1489
1490    StreamDPVmInstructionsRunner runner;
1491
1492    uint32_t random_per_thread=0;
1493
1494    int i;
1495    for (i=0; i<20; i++) {
1496        runner.run(&random_per_thread,
1497                   program_size,
1498                   vm.get_dp_instruction_buffer()->get_program(),
1499                   vm.get_bss_ptr(),
1500                   (uint8_t*)pcap.m_raw.raw);
1501
1502        assert(lpWriter->write_packet(&pcap.m_raw));
1503    }
1504
1505    delete lpWriter;
1506
1507    CErfCmp cmp;
1508
1509    bool res1=cmp.compare("exp/udp_64B_vm_mask1.pcap","exp/udp_64B_vm_mask1-ex.pcap");
1510    EXPECT_EQ(1, res1?1:0);
1511}
1512
1513
1514TEST_F(basic_vm, vm_mask2) {
1515
1516
1517
1518    StreamVm vm;
1519
1520    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
1521                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0x10000007,0x10000007,0x100000fe)  );
1522
1523
1524    vm.add_instruction( new StreamVmInstructionWriteMaskToPkt("var1", 36,2,0xff00,8,0,1) );
1525
1526    vm.compile(128);
1527
1528
1529    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1530
1531    printf (" program size : %lu \n",(ulong)program_size);
1532
1533
1534    vm.Dump(stdout);
1535
1536    CPcapLoader pcap;
1537    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1538
1539
1540    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask2.pcap");
1541    assert(lpWriter);
1542
1543
1544    StreamDPVmInstructionsRunner runner;
1545
1546    uint32_t random_per_thread=0;
1547
1548    int i;
1549    for (i=0; i<20; i++) {
1550        runner.run(&random_per_thread,
1551                   program_size,
1552                   vm.get_dp_instruction_buffer()->get_program(),
1553                   vm.get_bss_ptr(),
1554                   (uint8_t*)pcap.m_raw.raw);
1555
1556        assert(lpWriter->write_packet(&pcap.m_raw));
1557    }
1558
1559    delete lpWriter;
1560
1561    CErfCmp cmp;
1562
1563    bool res1=cmp.compare("exp/udp_64B_vm_mask2.pcap","exp/udp_64B_vm_mask2-ex.pcap");
1564    EXPECT_EQ(1, res1?1:0);
1565}
1566
1567TEST_F(basic_vm, vm_mask3) {
1568
1569
1570
1571    StreamVm vm;
1572
1573    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
1574                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0x10000007,0x10000007,0x100000fe)  );
1575
1576
1577    vm.add_instruction( new StreamVmInstructionWriteMaskToPkt("var1", 36,1,0x2,1,0,1) );
1578
1579    vm.compile(128);
1580
1581
1582    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1583
1584    printf (" program size : %lu \n",(ulong)program_size);
1585
1586
1587    vm.Dump(stdout);
1588
1589    CPcapLoader pcap;
1590    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1591
1592
1593    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask3.pcap");
1594    assert(lpWriter);
1595
1596
1597    StreamDPVmInstructionsRunner runner;
1598
1599    uint32_t random_per_thread=0;
1600
1601    int i;
1602    for (i=0; i<20; i++) {
1603        runner.run(&random_per_thread,
1604                   program_size,
1605                   vm.get_dp_instruction_buffer()->get_program(),
1606                   vm.get_bss_ptr(),
1607                   (uint8_t*)pcap.m_raw.raw);
1608
1609        assert(lpWriter->write_packet(&pcap.m_raw));
1610    }
1611
1612    delete lpWriter;
1613
1614    CErfCmp cmp;
1615
1616    bool res1=cmp.compare("exp/udp_64B_vm_mask3.pcap","exp/udp_64B_vm_mask3-ex.pcap");
1617    EXPECT_EQ(1, res1?1:0);
1618}
1619
1620TEST_F(basic_vm, vm_mask4) {
1621
1622
1623
1624    StreamVm vm;
1625
1626    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1 /* size */,
1627                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,1,1,10)  );
1628
1629
1630    vm.add_instruction( new StreamVmInstructionWriteMaskToPkt("var1", 36,2,0xFF00,8,0,1) );
1631
1632    vm.compile(128);
1633
1634
1635    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1636
1637    printf (" program size : %lu \n",(ulong)program_size);
1638
1639
1640    vm.Dump(stdout);
1641
1642    CPcapLoader pcap;
1643    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1644
1645
1646    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask4.pcap");
1647    assert(lpWriter);
1648
1649
1650    StreamDPVmInstructionsRunner runner;
1651
1652    uint32_t random_per_thread=0;
1653
1654    int i;
1655    for (i=0; i<20; i++) {
1656        runner.run(&random_per_thread,
1657                   program_size,
1658                   vm.get_dp_instruction_buffer()->get_program(),
1659                   vm.get_bss_ptr(),
1660                   (uint8_t*)pcap.m_raw.raw);
1661
1662        assert(lpWriter->write_packet(&pcap.m_raw));
1663    }
1664
1665    delete lpWriter;
1666
1667    CErfCmp cmp;
1668
1669    bool res1=cmp.compare("exp/udp_64B_vm_mask4.pcap","exp/udp_64B_vm_mask4-ex.pcap");
1670    EXPECT_EQ(1, res1?1:0);
1671}
1672
1673TEST_F(basic_vm, vm_mask5) {
1674
1675
1676
1677    StreamVm vm;
1678
1679    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1 /* size */,
1680                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,1,1,10)  );
1681
1682
1683    vm.add_instruction( new StreamVmInstructionWriteMaskToPkt("var1", 36,4,0x00FF0000,16,0,1) );
1684
1685    vm.compile(128);
1686
1687
1688    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1689
1690    printf (" program size : %lu \n",(ulong)program_size);
1691
1692
1693    vm.Dump(stdout);
1694
1695    CPcapLoader pcap;
1696    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1697
1698
1699    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask5.pcap");
1700    assert(lpWriter);
1701
1702
1703    StreamDPVmInstructionsRunner runner;
1704
1705    uint32_t random_per_thread=0;
1706
1707    int i;
1708    for (i=0; i<20; i++) {
1709        runner.run(&random_per_thread,
1710                   program_size,
1711                   vm.get_dp_instruction_buffer()->get_program(),
1712                   vm.get_bss_ptr(),
1713                   (uint8_t*)pcap.m_raw.raw);
1714
1715        assert(lpWriter->write_packet(&pcap.m_raw));
1716    }
1717
1718    delete lpWriter;
1719
1720    CErfCmp cmp;
1721
1722    bool res1=cmp.compare("exp/udp_64B_vm_mask5.pcap","exp/udp_64B_vm_mask5-ex.pcap");
1723    EXPECT_EQ(1, res1?1:0);
1724}
1725
1726
1727TEST_F(basic_vm, vm_mask6) {
1728
1729
1730
1731    StreamVm vm;
1732
1733    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
1734                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,1,1,20)  );
1735
1736
1737    vm.add_instruction( new StreamVmInstructionWriteMaskToPkt("var1", 36,2,0x00FF,-1,0,1) );
1738
1739    vm.compile(128);
1740
1741
1742    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1743
1744    printf (" program size : %lu \n",(ulong)program_size);
1745
1746
1747    vm.Dump(stdout);
1748
1749    CPcapLoader pcap;
1750    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1751
1752
1753    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask6.pcap");
1754    assert(lpWriter);
1755
1756
1757    StreamDPVmInstructionsRunner runner;
1758
1759    uint32_t random_per_thread=0;
1760
1761    int i;
1762    for (i=0; i<20; i++) {
1763        runner.run(&random_per_thread,
1764                   program_size,
1765                   vm.get_dp_instruction_buffer()->get_program(),
1766                   vm.get_bss_ptr(),
1767                   (uint8_t*)pcap.m_raw.raw);
1768
1769        assert(lpWriter->write_packet(&pcap.m_raw));
1770    }
1771
1772    delete lpWriter;
1773
1774    CErfCmp cmp;
1775
1776    bool res1=cmp.compare("exp/udp_64B_vm_mask6.pcap","exp/udp_64B_vm_mask6-ex.pcap");
1777    EXPECT_EQ(1, res1?1:0);
1778}
1779
1780////////////////////////////////////////////////////////
1781
1782
1783TEST_F(basic_vm, vm8) {
1784
1785
1786
1787    StreamVm vm;
1788
1789    vm.add_instruction( new StreamVmInstructionFlowClient( "cl1",
1790                                                           0x10000001,
1791                                                           0x10000006,
1792                                                           1025,
1793                                                           1027,
1794                                                           4,
1795                                                           0) );
1796
1797    /* src ip */
1798    vm.add_instruction( new StreamVmInstructionWriteToPkt( "cl1.ip",26, 0,true)
1799                        );
1800
1801    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
1802
1803    /* src port */
1804    vm.add_instruction( new StreamVmInstructionWriteToPkt( "cl1.port",34, 0,true)
1805                        );
1806
1807
1808    vm.compile(128);
1809
1810
1811    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1812
1813    printf (" program size : %lu \n",(ulong)program_size);
1814
1815
1816    vm.Dump(stdout);
1817
1818    CPcapLoader pcap;
1819    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1820
1821
1822
1823    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm8.pcap");
1824    assert(lpWriter);
1825
1826
1827    StreamDPVmInstructionsRunner runner;
1828
1829    uint32_t random_per_thread=0;
1830
1831    int i;
1832    for (i=0; i<20; i++) {
1833        runner.run(&random_per_thread,
1834                   program_size,
1835                   vm.get_dp_instruction_buffer()->get_program(),
1836                   vm.get_bss_ptr(),
1837                   (uint8_t*)pcap.m_raw.raw);
1838
1839        assert(lpWriter->write_packet(&pcap.m_raw));
1840    }
1841
1842    delete lpWriter;
1843
1844    CErfCmp cmp;
1845
1846    bool res1=cmp.compare("exp/udp_64B_vm8.pcap","exp/udp_64B_vm8-ex.pcap");
1847    EXPECT_EQ(1, res1?1:0);
1848}
1849
1850static void vm_build_program_seq(StreamVm & vm,
1851                                 uint16_t packet_size,
1852                                 bool should_compile){
1853
1854    vm.add_instruction( new StreamVmInstructionFlowClient( "tuple_gen",
1855                                                           0x10000001,
1856                                                           0x10000006,
1857                                                           1025,
1858                                                           1027,
1859                                                           20,
1860                                                           0) );
1861
1862    /* src ip */
1863    vm.add_instruction( new StreamVmInstructionWriteToPkt( "tuple_gen.ip",26, 0,true)
1864                        );
1865
1866    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
1867
1868    /* src port */
1869    vm.add_instruction( new StreamVmInstructionWriteToPkt( "tuple_gen.port",34, 0,true)
1870                        );
1871
1872    if (should_compile) {
1873        vm.compile(packet_size);
1874    }
1875}
1876
1877
1878TEST_F(basic_vm, vm9) {
1879
1880
1881    StreamVm vm;
1882
1883    vm_build_program_seq(vm,128, true);
1884
1885    printf(" max packet update %lu \n",(ulong)vm.get_max_packet_update_offset());
1886
1887    EXPECT_EQ(36,vm.get_max_packet_update_offset());
1888
1889    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1890
1891    printf (" program size : %lu \n",(ulong)program_size);
1892
1893
1894    vm.Dump(stdout);
1895
1896    CPcapLoader pcap;
1897    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1898
1899
1900
1901    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm9.pcap");
1902    assert(lpWriter);
1903
1904
1905    StreamDPVmInstructionsRunner runner;
1906
1907    uint32_t random_per_thread=0;
1908
1909    int i;
1910    for (i=0; i<30; i++) {
1911        runner.run(&random_per_thread,
1912                   program_size,
1913                   vm.get_dp_instruction_buffer()->get_program(),
1914                   vm.get_bss_ptr(),
1915                   (uint8_t*)pcap.m_raw.raw);
1916
1917        assert(lpWriter->write_packet(&pcap.m_raw));
1918    }
1919
1920    delete lpWriter;
1921
1922    CErfCmp cmp;
1923
1924    bool res1=cmp.compare("exp/udp_64B_vm9.pcap","exp/udp_64B_vm9-ex.pcap");
1925    EXPECT_EQ(1, res1?1:0);
1926}
1927
1928
1929/* test vmDP object */
1930TEST_F(basic_vm, vm10) {
1931
1932    StreamVm vm;
1933
1934    vm_build_program_seq(vm,128, true);
1935
1936    printf(" max packet update %lu \n",(ulong)vm.get_max_packet_update_offset());
1937
1938    EXPECT_EQ(36,vm.get_max_packet_update_offset());
1939
1940    StreamVmDp * lpDpVm =vm.generate_dp_object();
1941
1942    EXPECT_EQ(lpDpVm->get_bss_size(),vm.get_bss_size());
1943
1944    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1945
1946    printf (" program size : %lu \n",(ulong)program_size);
1947
1948
1949    vm.Dump(stdout);
1950
1951    CPcapLoader pcap;
1952    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1953
1954
1955
1956    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm9.pcap");
1957    assert(lpWriter);
1958
1959
1960    StreamDPVmInstructionsRunner runner;
1961
1962    uint32_t random_per_thread=0;
1963
1964    int i;
1965    for (i=0; i<30; i++) {
1966
1967        runner.run(&random_per_thread,
1968                   lpDpVm->get_program_size(),
1969                   lpDpVm->get_program(),
1970                   lpDpVm->get_bss(),
1971                   (uint8_t*)pcap.m_raw.raw);
1972
1973        assert(lpWriter->write_packet(&pcap.m_raw));
1974    }
1975
1976    delete lpWriter;
1977
1978    CErfCmp cmp;
1979    delete  lpDpVm;
1980
1981    bool res1=cmp.compare("exp/udp_64B_vm9.pcap","exp/udp_64B_vm9-ex.pcap");
1982    EXPECT_EQ(1, res1?1:0);
1983}
1984
1985
1986/* test vmDP object */
1987TEST_F(basic_vm, vm_syn_attack) {
1988
1989    StreamVm vm;
1990    srand(0x1234);
1991
1992    vm.add_instruction( new StreamVmInstructionFlowMan( "ip_src",
1993                                                        4,
1994                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
1995                                                        0,
1996                                                        0,
1997                                                        1000000));
1998
1999    vm.add_instruction( new StreamVmInstructionFlowMan( "ip_dst",
2000                                                        4,
2001                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
2002                                                        0,
2003                                                        0,
2004                                                        1000000));
2005
2006    vm.add_instruction( new StreamVmInstructionFlowMan( "src_port",
2007                                                        2,
2008                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
2009                                                        1025,
2010                                                        1025,
2011                                                        65000));
2012
2013    vm.add_instruction( new StreamVmInstructionFlowMan( "dst_port",
2014                                                        2,
2015                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
2016                                                        1025,
2017                                                        1025,
2018                                                        65000));
2019
2020    /* src ip */
2021    vm.add_instruction( new StreamVmInstructionWriteToPkt( "ip_src",26, 0x10000000,true)
2022                        );
2023
2024    vm.add_instruction( new StreamVmInstructionWriteToPkt( "ip_dst",26+4, 0x40000000,true)
2025                        );
2026
2027    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
2028
2029    /* src port */
2030    vm.add_instruction( new StreamVmInstructionWriteToPkt( "src_port",34, 0,true)
2031                        );
2032    vm.add_instruction( new StreamVmInstructionWriteToPkt( "dst_port",34+2, 0,true)
2033                        );
2034
2035    vm.compile(128);
2036
2037    printf(" max packet update %lu \n",(ulong)vm.get_max_packet_update_offset());
2038
2039    EXPECT_EQ(38,vm.get_max_packet_update_offset());
2040
2041    StreamVmDp * lpDpVm =vm.generate_dp_object();
2042
2043    EXPECT_EQ(lpDpVm->get_bss_size(),vm.get_bss_size());
2044
2045    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
2046
2047    printf (" program size : %lu \n",(ulong)program_size);
2048
2049
2050    vm.Dump(stdout);
2051
2052    CPcapLoader pcap;
2053    pcap.load_pcap_file("stl/yaml/syn_packet.pcap",0);
2054
2055
2056
2057    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/stl_syn_attack.pcap");
2058    assert(lpWriter);
2059
2060
2061    StreamDPVmInstructionsRunner runner;
2062
2063    uint32_t random_per_thread=0;
2064
2065    int i;
2066    for (i=0; i<30; i++) {
2067
2068        runner.run(&random_per_thread,
2069                   lpDpVm->get_program_size(),
2070                   lpDpVm->get_program(),
2071                   lpDpVm->get_bss(),
2072                   (uint8_t*)pcap.m_raw.raw);
2073
2074        assert(lpWriter->write_packet(&pcap.m_raw));
2075    }
2076
2077    delete lpWriter;
2078
2079    CErfCmp cmp;
2080    delete  lpDpVm;
2081
2082    bool res1=cmp.compare("exp/stl_syn_attack.pcap","exp/stl_syn_attack-ex.pcap");
2083    EXPECT_EQ(1, res1?1:0);
2084}
2085
2086
2087void run_vm_program( StreamVm & vm,
2088                    std::string input_pcap_file,
2089                    std::string out_file_name,
2090                    int num_pkts
2091                    ){
2092
2093    CPcapLoader pcap;
2094    pcap.load_pcap_file(input_pcap_file,0);
2095
2096    printf(" packet size : %lu \n",(ulong)pcap.m_raw.pkt_len);
2097    vm.compile(pcap.m_raw.pkt_len);
2098
2099    StreamVmDp * lpDpVm =vm.generate_dp_object();
2100
2101    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
2102
2103    printf (" program size : %lu \n",(ulong)program_size);
2104
2105    vm.Dump(stdout);
2106
2107    std::string out_file_full ="exp/"+out_file_name +".pcap";
2108    std::string out_file_ex_full ="exp/"+out_file_name +"-ex.pcap";
2109
2110    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)out_file_full.c_str());
2111    assert(lpWriter);
2112
2113
2114    StreamDPVmInstructionsRunner runner;
2115
2116    uint32_t random_per_thread=0;
2117
2118    int i;
2119    for (i=0; i<num_pkts; i++) {
2120
2121        runner.run(&random_per_thread,
2122                   lpDpVm->get_program_size(),
2123                   lpDpVm->get_program(),
2124                   lpDpVm->get_bss(),
2125                   (uint8_t*)pcap.m_raw.raw);
2126        uint16_t new_pkt_size=runner.get_new_pkt_size();
2127        assert(new_pkt_size>0);
2128        if (new_pkt_size ==0) {
2129            assert(lpWriter->write_packet(&pcap.m_raw));
2130        }else{
2131            /* we can only reduce */
2132            if (new_pkt_size>pcap.m_raw.pkt_len) {
2133                new_pkt_size=pcap.m_raw.pkt_len;
2134            }
2135            CCapPktRaw np(new_pkt_size);
2136             np.time_sec  = pcap.m_raw.time_sec;
2137             np.time_nsec = pcap.m_raw.time_nsec;
2138             np.pkt_cnt   = pcap.m_raw.pkt_cnt;
2139             memcpy(np.raw,pcap.m_raw.raw,new_pkt_size);
2140             assert(lpWriter->write_packet(&np));
2141        }
2142    }
2143
2144    delete lpWriter;
2145
2146    CErfCmp cmp;
2147    delete  lpDpVm;
2148
2149    bool res1=cmp.compare(out_file_full.c_str() ,out_file_ex_full.c_str());
2150    EXPECT_EQ(1, res1?1:0);
2151}
2152
2153
2154TEST_F(basic_vm, vm_inc_size_64_128) {
2155
2156    StreamVm vm;
2157
2158    vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var",
2159                                                        2,                // size var  must be 16bit size
2160                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,
2161                                                        128,
2162                                                        128,
2163                                                        256));
2164
2165    vm.add_instruction( new StreamVmInstructionChangePktSize( "rand_pkt_size_var"));
2166
2167    /* src ip */
2168    /*14+ 2 , remove the */
2169
2170    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",16, -14,true)
2171                        );
2172
2173    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
2174
2175    /* update UDP length */
2176    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",32+6, -(14+20),true)
2177                        );
2178
2179    run_vm_program(vm,"stl/yaml/udp_1518B_no_crc.pcap","stl_vm_inc_size_64_128",20);
2180}
2181
2182TEST_F(basic_vm, vm_random_size_64_128) {
2183
2184    StreamVm vm;
2185    srand(0x1234);
2186
2187    vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var",
2188                                                        2,                // size var  must be 16bit size
2189                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
2190                                                        128,
2191                                                        128,
2192                                                        256));
2193
2194    vm.add_instruction( new StreamVmInstructionChangePktSize( "rand_pkt_size_var"));
2195
2196    /* src ip */
2197    /*14+ 2 , remove the */
2198
2199    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",16, -14,true)
2200                        );
2201
2202    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
2203
2204    /* update UDP length */
2205    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",32+6, -(14+20),true)
2206                        );
2207
2208
2209    run_vm_program(vm,"stl/yaml/udp_1518B_no_crc.pcap","stl_vm_rand_size_64_128",20);
2210
2211}
2212
2213
2214
2215/* should have exception packet size is smaller than range */
2216TEST_F(basic_vm, vm_random_size_64_127_128) {
2217
2218    StreamVm vm;
2219    srand(0x1234);
2220
2221    vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var",
2222                                                        2,                // size var  must be 16bit size
2223                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
2224                                                        128,
2225                                                        128,
2226                                                        256));
2227
2228    vm.add_instruction( new StreamVmInstructionChangePktSize( "rand_pkt_size_var"));
2229
2230    /* src ip */
2231    /*14+ 2 , remove the */
2232
2233    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",16, -14,true)
2234                        );
2235
2236    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
2237
2238    /* update UDP length */
2239    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",32+6, -(14+20),true)
2240                        );
2241
2242    bool fail=false;
2243
2244    try {
2245       run_vm_program(vm,"stl/yaml/udp_64B_no_crc.pcap","stl_vm_rand_size_64B_127_128",20);
2246     } catch (const TrexException &ex) {
2247        fail=true;
2248    }
2249
2250    EXPECT_EQ(true, fail);
2251
2252}
2253
2254
2255TEST_F(basic_vm, vm_random_size_500b_0_9k) {
2256
2257    StreamVm vm;
2258    srand(0x1234);
2259
2260    vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var",
2261                                                        2,                // size var  must be 16bit size
2262                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
2263                                                        0,
2264                                                        0,
2265                                                        9*1024));
2266
2267    vm.add_instruction( new StreamVmInstructionChangePktSize( "rand_pkt_size_var"));
2268
2269    /* src ip */
2270    /*14+ 2 , remove the */
2271
2272    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",16, -14,true)
2273                        );
2274
2275    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
2276
2277    /* update UDP length */
2278    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",32+6, -(14+20),true)
2279                        );
2280
2281    run_vm_program(vm,"stl/yaml/udp_594B_no_crc.pcap","stl_vm_rand_size_512B_64_128",10);
2282
2283}
2284
2285
2286
2287//////////////////////////////////////////////////////
2288
2289
2290#define EXPECT_EQ_UINT32(a,b) EXPECT_EQ((uint32_t)(a),(uint32_t)(b))
2291
2292
2293
2294/* basic stateless test */
2295class basic_stl  : public testing::Test {
2296 protected:
2297  virtual void SetUp() {
2298  }
2299  virtual void TearDown() {
2300  }
2301public:
2302};
2303
2304
2305/**
2306 * Queue of RPC msgs for test
2307 *
2308 * @author hhaim
2309 */
2310
2311class CBasicStl;
2312
2313
2314struct CBasicStlDelayCommand {
2315
2316    CBasicStlDelayCommand(){
2317        m_node=NULL;
2318    }
2319    CGenNodeCommand * m_node;
2320};
2321
2322
2323
2324class CBasicStlMsgQueue {
2325
2326friend CBasicStl;
2327
2328public:
2329    CBasicStlMsgQueue(){
2330    }
2331
2332    /* user will allocate the message,  no need to free it by this module */
2333    void add_msg(TrexStatelessCpToDpMsgBase * msg){
2334        m_msgs.push_back(msg);
2335    }
2336
2337    void add_command(CBasicStlDelayCommand & command){
2338        m_commands.push_back(command);
2339    }
2340
2341        /* only if both port are idle we can exit */
2342    void add_command(CFlowGenListPerThread   * core,
2343                     TrexStatelessCpToDpMsgBase * msg,
2344                     double time){
2345
2346        CGenNodeCommand *node = (CGenNodeCommand *)core->create_node() ;
2347
2348        node->m_type = CGenNode::COMMAND;
2349
2350        node->m_cmd = msg;
2351
2352        /* make sure it will be scheduled after the current node */
2353        node->m_time = time ;
2354
2355        CBasicStlDelayCommand command;
2356        command.m_node =node;
2357
2358        add_command(command);
2359    }
2360
2361
2362    void clear(){
2363        m_msgs.clear();
2364        m_commands.clear();
2365    }
2366
2367
2368protected:
2369    std::vector<TrexStatelessCpToDpMsgBase *> m_msgs;
2370
2371    std::vector<CBasicStlDelayCommand> m_commands;
2372};
2373
2374
2375
2376class CBasicStlSink {
2377
2378public:
2379    CBasicStlSink(){
2380        m_core=0;
2381    }
2382    virtual void call_after_init(CBasicStl * m_obj)=0;
2383    virtual void call_after_run(CBasicStl * m_obj)=0;
2384
2385    CFlowGenListPerThread   * m_core;
2386};
2387
2388
2389/**
2390 * handler for DP to CP messages
2391 *
2392 * @author imarom (19-Nov-15)
2393 */
2394class DpToCpHandler {
2395public:
2396    virtual void handle(TrexStatelessDpToCpMsgBase *msg) = 0;
2397};
2398
2399class CBasicStl {
2400
2401public:
2402
2403
2404    CBasicStl(){
2405        m_time_diff=0.001;
2406        m_threads=1;
2407        m_dump_json=false;
2408        m_dp_to_cp_handler = NULL;
2409        m_msg = NULL;
2410        m_sink = NULL;
2411    }
2412
2413
2414    void flush_dp_to_cp_messages() {
2415
2416        CNodeRing *ring = CMsgIns::Ins()->getCpDp()->getRingDpToCp(0);
2417
2418        while ( true ) {
2419            CGenNode * node = NULL;
2420            if (ring->Dequeue(node) != 0) {
2421                break;
2422            }
2423            assert(node);
2424
2425            TrexStatelessDpToCpMsgBase * msg = (TrexStatelessDpToCpMsgBase *)node;
2426            if (m_dp_to_cp_handler) {
2427                m_dp_to_cp_handler->handle(msg);
2428            }
2429
2430            delete msg;
2431        }
2432
2433    }
2434
2435
2436    bool  init(void){
2437
2438        CErfIFStl erf_vif;
2439        fl.Create();
2440        fl.generate_p_thread_info(1);
2441        CFlowGenListPerThread   * lpt;
2442
2443        fl.m_threads_info[0]->set_vif(&erf_vif);
2444
2445        CErfCmp cmp;
2446        cmp.dump=1;
2447
2448        CMessagingManager * cp_dp = CMsgIns::Ins()->getCpDp();
2449
2450        m_ring_from_cp = cp_dp->getRingCpToDp(0);
2451
2452
2453        bool res=true;
2454
2455        lpt=fl.m_threads_info[0];
2456
2457        if ( m_sink ){
2458            m_sink->m_core =lpt;
2459        }
2460
2461        char buf[100];
2462        char buf_ex[100];
2463        sprintf(buf,"%s-%d.erf",CGlobalInfo::m_options.out_file.c_str(),0);
2464        sprintf(buf_ex,"%s-%d-ex.erf",CGlobalInfo::m_options.out_file.c_str(),0);
2465
2466        lpt->start_stateless_simulation_file(buf,CGlobalInfo::m_options.preview);
2467
2468        /* add stream to the queue */
2469        if ( m_msg ) {
2470            assert(m_ring_from_cp->Enqueue((CGenNode *)m_msg)==0);
2471        }
2472        if (m_msg_queue.m_msgs.size()>0) {
2473            for (auto msg : m_msg_queue.m_msgs) {
2474                assert(m_ring_from_cp->Enqueue((CGenNode *)msg)==0);
2475            }
2476        }
2477
2478        if (m_sink) {
2479            m_sink->call_after_init(this);
2480        }
2481
2482        /* add the commands */
2483        if (m_msg_queue.m_commands.size()>0) {
2484            for (auto cmd : m_msg_queue.m_commands) {
2485                /* add commands nodes */
2486                lpt->m_node_gen.add_node((CGenNode *)cmd.m_node);
2487            }
2488        }
2489
2490        lpt->start_stateless_daemon_simulation();
2491        lpt->stop_stateless_simulation_file();
2492
2493        //lpt->m_node_gen.DumpHist(stdout);
2494
2495        cmp.d_sec = m_time_diff;
2496
2497        if ( cmp.compare(std::string(buf),std::string(buf_ex)) != true ) {
2498            res=false;
2499        }
2500
2501        if ( m_dump_json ){
2502            printf(" dump json ...........\n");
2503            std::string s;
2504            fl.m_threads_info[0]->m_node_gen.dump_json(s);
2505            printf(" %s \n",s.c_str());
2506        }
2507
2508        if (m_sink) {
2509            m_sink->call_after_run(this);
2510        }
2511
2512        flush_dp_to_cp_messages();
2513        m_msg_queue.clear();
2514
2515
2516        fl.Delete();
2517        return (res);
2518    }
2519
2520public:
2521    int               m_threads;
2522    double            m_time_diff;
2523    bool              m_dump_json;
2524    DpToCpHandler     *m_dp_to_cp_handler;
2525    CBasicStlSink     * m_sink;
2526
2527    TrexStatelessCpToDpMsgBase * m_msg;
2528    CNodeRing           *m_ring_from_cp;
2529    CBasicStlMsgQueue    m_msg_queue;
2530    CFlowGenList  fl;
2531};
2532
2533
2534
2535TEST_F(basic_stl, load_pcap_file) {
2536    printf (" stateles %d \n",(int)sizeof(CGenNodeStateless));
2537
2538    CPcapLoader pcap;
2539    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2540    pcap.update_ip_src(0x10000001);
2541    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2542    pcap.update_ip_src(0x10000001);
2543
2544    //pcap.dump_packet();
2545}
2546
2547
2548
2549class CBBStartPause0: public CBasicStlSink {
2550public:
2551
2552    virtual void call_after_init(CBasicStl * m_obj);
2553    virtual void call_after_run(CBasicStl * m_obj){
2554    };
2555    uint8_t m_port_id;
2556};
2557
2558
2559
2560void CBBStartPause0::call_after_init(CBasicStl * m_obj){
2561
2562    TrexStatelessDpPause * lpPauseCmd = new TrexStatelessDpPause(m_port_id);
2563    TrexStatelessDpResume * lpResumeCmd1 = new TrexStatelessDpResume(m_port_id);
2564
2565    m_obj->m_msg_queue.add_command(m_core,lpPauseCmd, 5.0); /* command in delay of 5 sec */
2566    m_obj->m_msg_queue.add_command(m_core,lpResumeCmd1, 7.0);/* command in delay of 7 sec */
2567
2568}
2569
2570
2571
2572/* start/stop/stop back to back */
2573TEST_F(basic_stl, basic_pause_resume0) {
2574
2575    CBasicStl t1;
2576    CParserOption * po =&CGlobalInfo::m_options;
2577    po->preview.setVMode(7);
2578    po->preview.setFileWrite(true);
2579    po->out_file ="exp/stl_basic_pause_resume0";
2580
2581     TrexStreamsCompiler compile;
2582
2583     uint8_t port_id=0;
2584
2585     std::vector<TrexStream *> streams;
2586
2587     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2588     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2589
2590
2591     stream1->m_enabled = true;
2592     stream1->m_self_start = true;
2593     stream1->m_port_id= port_id;
2594
2595
2596     CPcapLoader pcap;
2597     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2598     pcap.update_ip_src(0x10000001);
2599     pcap.clone_packet_into_stream(stream1);
2600
2601     streams.push_back(stream1);
2602
2603     // stream - clean
2604
2605     std::vector<TrexStreamsCompiledObj *> objs;
2606     assert(compile.compile(port_id, streams, objs));
2607     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2608
2609     t1.m_msg_queue.add_msg(lpStartCmd);
2610
2611
2612     CBBStartPause0 sink;
2613     sink.m_port_id = port_id;
2614     t1.m_sink =  &sink;
2615
2616     bool res=t1.init();
2617
2618     delete stream1 ;
2619
2620     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2621}
2622
2623
2624//////////////////////////////////////////////////////////////
2625
2626
2627class CBBStartStopDelay2: public CBasicStlSink {
2628public:
2629
2630    virtual void call_after_init(CBasicStl * m_obj);
2631    virtual void call_after_run(CBasicStl * m_obj){
2632    };
2633    uint8_t m_port_id;
2634};
2635
2636
2637
2638void CBBStartStopDelay2::call_after_init(CBasicStl * m_obj){
2639
2640    TrexStatelessDpStop * lpStopCmd = new TrexStatelessDpStop(m_port_id);
2641    TrexStatelessDpStop * lpStopCmd1 = new TrexStatelessDpStop(m_port_id);
2642
2643
2644    TrexStreamsCompiler compile;
2645
2646    uint8_t port_id=0;
2647
2648    std::vector<TrexStream *> streams;
2649
2650    TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2651    stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2652
2653
2654    stream1->m_enabled = true;
2655    stream1->m_self_start = true;
2656    stream1->m_port_id= port_id;
2657
2658
2659    CPcapLoader pcap;
2660    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2661    pcap.update_ip_src(0x10000002);
2662    pcap.clone_packet_into_stream(stream1);
2663
2664    streams.push_back(stream1);
2665
2666    // stream - clean
2667    std::vector<TrexStreamsCompiledObj *>objs;
2668    assert(compile.compile(port_id, streams, objs));
2669    TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 1, objs[0], 10.0 /*sec */ );
2670
2671
2672    m_obj->m_msg_queue.add_command(m_core,lpStopCmd, 5.0); /* command in delay of 5 sec */
2673    m_obj->m_msg_queue.add_command(m_core,lpStopCmd1, 7.0);/* command in delay of 7 sec */
2674    m_obj->m_msg_queue.add_command(m_core,lpStartCmd, 7.5);/* command in delay of 7 sec */
2675
2676    delete stream1 ;
2677
2678
2679}
2680
2681
2682
2683/* start/stop/stop back to back */
2684TEST_F(basic_stl, single_pkt_bb_start_stop_delay2) {
2685
2686    CBasicStl t1;
2687    CParserOption * po =&CGlobalInfo::m_options;
2688    po->preview.setVMode(7);
2689    po->preview.setFileWrite(true);
2690    po->out_file ="exp/stl_bb_start_stop_delay2";
2691
2692     TrexStreamsCompiler compile;
2693
2694     uint8_t port_id=0;
2695
2696     std::vector<TrexStream *> streams;
2697
2698     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2699     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2700
2701
2702     stream1->m_enabled = true;
2703     stream1->m_self_start = true;
2704     stream1->m_port_id= port_id;
2705
2706
2707     CPcapLoader pcap;
2708     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2709     pcap.update_ip_src(0x10000001);
2710     pcap.clone_packet_into_stream(stream1);
2711
2712     streams.push_back(stream1);
2713
2714     // stream - clean
2715     std::vector<TrexStreamsCompiledObj *>objs;
2716     assert(compile.compile(port_id, streams, objs));
2717     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2718
2719     t1.m_msg_queue.add_msg(lpStartCmd);
2720
2721
2722     CBBStartStopDelay2 sink;
2723     sink.m_port_id = port_id;
2724     t1.m_sink =  &sink;
2725
2726     bool res=t1.init();
2727
2728     delete stream1 ;
2729
2730     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2731}
2732
2733
2734
2735
2736
2737
2738
2739class CBBStartStopDelay1: public CBasicStlSink {
2740public:
2741
2742    virtual void call_after_init(CBasicStl * m_obj);
2743    virtual void call_after_run(CBasicStl * m_obj){
2744    };
2745    uint8_t m_port_id;
2746};
2747
2748
2749
2750void CBBStartStopDelay1::call_after_init(CBasicStl * m_obj){
2751
2752    TrexStatelessDpStop * lpStopCmd = new TrexStatelessDpStop(m_port_id);
2753    TrexStatelessDpStop * lpStopCmd1 = new TrexStatelessDpStop(m_port_id);
2754
2755    m_obj->m_msg_queue.add_command(m_core,lpStopCmd, 5.0); /* command in delay of 5 sec */
2756    m_obj->m_msg_queue.add_command(m_core,lpStopCmd1, 7.0);/* command in delay of 7 sec */
2757}
2758
2759
2760
2761/* start/stop/stop back to back */
2762TEST_F(basic_stl, single_pkt_bb_start_stop_delay1) {
2763
2764    CBasicStl t1;
2765    CParserOption * po =&CGlobalInfo::m_options;
2766    po->preview.setVMode(7);
2767    po->preview.setFileWrite(true);
2768    po->out_file ="exp/stl_bb_start_stop_delay1";
2769
2770     TrexStreamsCompiler compile;
2771
2772     uint8_t port_id=0;
2773
2774     std::vector<TrexStream *> streams;
2775
2776     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2777     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2778
2779
2780     stream1->m_enabled = true;
2781     stream1->m_self_start = true;
2782     stream1->m_port_id= port_id;
2783
2784
2785     CPcapLoader pcap;
2786     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2787     pcap.update_ip_src(0x10000001);
2788     pcap.clone_packet_into_stream(stream1);
2789
2790     streams.push_back(stream1);
2791
2792     // stream - clean
2793     std::vector<TrexStreamsCompiledObj *>objs;
2794     assert(compile.compile(port_id, streams, objs));
2795     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2796
2797     t1.m_msg_queue.add_msg(lpStartCmd);
2798
2799
2800     CBBStartStopDelay1 sink;
2801     sink.m_port_id = port_id;
2802     t1.m_sink =  &sink;
2803
2804     bool res=t1.init();
2805
2806     delete stream1 ;
2807
2808     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2809}
2810
2811
2812/* start/stop/stop back to back */
2813TEST_F(basic_stl, single_pkt_bb_start_stop3) {
2814
2815    CBasicStl t1;
2816    CParserOption * po =&CGlobalInfo::m_options;
2817    po->preview.setVMode(7);
2818    po->preview.setFileWrite(true);
2819    po->out_file ="exp/stl_bb_start_stop3";
2820
2821     TrexStreamsCompiler compile;
2822
2823     uint8_t port_id=0;
2824
2825     std::vector<TrexStream *> streams;
2826
2827     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2828     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2829
2830
2831     stream1->m_enabled = true;
2832     stream1->m_self_start = true;
2833     stream1->m_port_id= port_id;
2834
2835
2836     CPcapLoader pcap;
2837     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2838     pcap.update_ip_src(0x10000001);
2839     pcap.clone_packet_into_stream(stream1);
2840
2841     streams.push_back(stream1);
2842
2843     // stream - clean
2844     std::vector<TrexStreamsCompiledObj *>objs;
2845     assert(compile.compile(port_id, streams, objs));
2846     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2847
2848     TrexStatelessDpStop * lpStopCmd = new TrexStatelessDpStop(port_id);
2849     TrexStatelessDpStop * lpStopCmd1 = new TrexStatelessDpStop(port_id);
2850
2851
2852     t1.m_msg_queue.add_msg(lpStartCmd);
2853     t1.m_msg_queue.add_msg(lpStopCmd);
2854     t1.m_msg_queue.add_msg(lpStopCmd1);
2855
2856     bool res=t1.init();
2857
2858     delete stream1 ;
2859
2860     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2861}
2862
2863
2864TEST_F(basic_stl, single_pkt_bb_start_stop2) {
2865
2866    CBasicStl t1;
2867    CParserOption * po =&CGlobalInfo::m_options;
2868    po->preview.setVMode(7);
2869    po->preview.setFileWrite(true);
2870    po->out_file ="exp/stl_bb_start_stop2";
2871
2872     TrexStreamsCompiler compile;
2873
2874     uint8_t port_id=0;
2875
2876     std::vector<TrexStream *> streams;
2877
2878     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2879     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2880
2881
2882     stream1->m_enabled = true;
2883     stream1->m_self_start = true;
2884     stream1->m_port_id= port_id;
2885
2886
2887     CPcapLoader pcap;
2888     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2889     pcap.update_ip_src(0x10000001);
2890     pcap.clone_packet_into_stream(stream1);
2891
2892     streams.push_back(stream1);
2893
2894     // stream - clean
2895     std::vector<TrexStreamsCompiledObj *>objs;
2896     assert(compile.compile(port_id, streams, objs));
2897     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2898
2899     TrexStatelessDpStop * lpStopCmd = new TrexStatelessDpStop(port_id);
2900     TrexStatelessDpStart * lpStartCmd1 = new TrexStatelessDpStart(port_id, 0, objs[0]->clone(), 10.0 /*sec */ );
2901
2902
2903     t1.m_msg_queue.add_msg(lpStartCmd);
2904     t1.m_msg_queue.add_msg(lpStopCmd);
2905     t1.m_msg_queue.add_msg(lpStartCmd1);
2906
2907     bool res=t1.init();
2908
2909     delete stream1 ;
2910
2911     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2912}
2913
2914
2915
2916/* back to back send start/stop */
2917TEST_F(basic_stl, single_pkt_bb_start_stop) {
2918
2919    CBasicStl t1;
2920    CParserOption * po =&CGlobalInfo::m_options;
2921    po->preview.setVMode(7);
2922    po->preview.setFileWrite(true);
2923    po->out_file ="exp/stl_bb_start_stop";
2924
2925     TrexStreamsCompiler compile;
2926
2927     uint8_t port_id=0;
2928
2929     std::vector<TrexStream *> streams;
2930
2931     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2932     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2933
2934
2935     stream1->m_enabled = true;
2936     stream1->m_self_start = true;
2937     stream1->m_port_id= port_id;
2938
2939
2940     CPcapLoader pcap;
2941     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2942     pcap.update_ip_src(0x10000001);
2943     pcap.clone_packet_into_stream(stream1);
2944
2945     streams.push_back(stream1);
2946
2947     // stream - clean
2948     std::vector<TrexStreamsCompiledObj *>objs;
2949     assert(compile.compile(port_id, streams, objs));
2950     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2951
2952     TrexStatelessDpStop * lpStopCmd = new TrexStatelessDpStop(port_id);
2953
2954
2955     t1.m_msg_queue.add_msg(lpStartCmd);
2956     t1.m_msg_queue.add_msg(lpStopCmd);
2957
2958     bool res=t1.init();
2959
2960     delete stream1 ;
2961
2962     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2963}
2964
2965
2966
2967
2968TEST_F(basic_stl, simple_prog4) {
2969
2970    CBasicStl t1;
2971    CParserOption * po =&CGlobalInfo::m_options;
2972    po->preview.setVMode(7);
2973    po->preview.setFileWrite(true);
2974    po->out_file ="exp/stl_simple_prog4";
2975
2976     TrexStreamsCompiler compile;
2977
2978
2979     std::vector<TrexStream *> streams;
2980
2981
2982     /* stream0 */
2983     TrexStream * stream0 = new TrexStream(TrexStream::stCONTINUOUS, 0,300);
2984     stream0->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2985     stream0->m_enabled = true;
2986     stream0->m_self_start = true;
2987
2988     CPcapLoader pcap;
2989     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2990     pcap.update_ip_src(0x10000000);
2991     pcap.clone_packet_into_stream(stream0);
2992     streams.push_back(stream0);
2993
2994
2995     /* stream1 */
2996     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100);
2997     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2998     stream1->set_single_burst(5);
2999     stream1->m_enabled = true;
3000     stream1->m_self_start = true;
3001     stream1->m_next_stream_id=200;
3002
3003     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3004     pcap.update_ip_src(0x10000001);
3005     pcap.clone_packet_into_stream(stream1);
3006
3007     streams.push_back(stream1);
3008
3009
3010     /* stream1 */
3011
3012     TrexStream * stream2 = new TrexStream(TrexStream::stMULTI_BURST, 0,200);
3013     stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3014     stream2->m_isg_usec = 1000000; /*time betwean stream 1 to stream 2 */
3015     stream2->m_enabled = true;
3016     stream2->m_self_start = false;
3017     stream2->set_multi_burst(5,
3018                              3,
3019                              2000000.0);
3020
3021     // next stream is 100 - loop
3022     stream2->m_next_stream_id=100;
3023
3024
3025     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3026     pcap.update_ip_src(0x10000002);
3027     pcap.clone_packet_into_stream(stream2);
3028     streams.push_back(stream2);
3029
3030
3031     uint8_t port_id = 0;
3032     std::vector<TrexStreamsCompiledObj *>objs;
3033     assert(compile.compile(port_id, streams, objs));
3034     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 20.0 /*sec */ );
3035
3036
3037     t1.m_msg = lpStartCmd;
3038
3039     bool res=t1.init();
3040
3041     delete stream0 ;
3042     delete stream1 ;
3043     delete stream2 ;
3044
3045     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3046}
3047
3048
3049
3050TEST_F(basic_stl, simple_prog3) {
3051
3052    CBasicStl t1;
3053    CParserOption * po =&CGlobalInfo::m_options;
3054    po->preview.setVMode(7);
3055    po->preview.setFileWrite(true);
3056    po->out_file ="exp/stl_simple_prog3";
3057
3058     TrexStreamsCompiler compile;
3059
3060
3061     std::vector<TrexStream *> streams;
3062
3063     /* stream1 */
3064     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100);
3065     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3066     stream1->set_single_burst(5);
3067     stream1->m_enabled = true;
3068     stream1->m_self_start = true;
3069     stream1->m_next_stream_id=200;
3070
3071     CPcapLoader pcap;
3072     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3073     pcap.update_ip_src(0x10000001);
3074     pcap.clone_packet_into_stream(stream1);
3075
3076     streams.push_back(stream1);
3077
3078
3079     /* stream1 */
3080
3081     TrexStream * stream2 = new TrexStream(TrexStream::stMULTI_BURST, 0,200);
3082     stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3083     stream2->m_isg_usec = 1000000; /*time betwean stream 1 to stream 2 */
3084     stream2->m_enabled = true;
3085     stream2->m_self_start = false;
3086     stream2->set_multi_burst(5,
3087                              3,
3088                              2000000.0);
3089
3090     // next stream is 100 - loop
3091     stream2->m_next_stream_id=100;
3092
3093
3094     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3095     pcap.update_ip_src(0x10000002);
3096     pcap.clone_packet_into_stream(stream2);
3097     streams.push_back(stream2);
3098
3099
3100     uint8_t port_id = 0;
3101     std::vector<TrexStreamsCompiledObj *>objs;
3102     assert(compile.compile(port_id, streams, objs));
3103     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 50.0 /*sec */ );
3104
3105
3106     t1.m_msg = lpstart;
3107
3108     bool res=t1.init();
3109
3110     delete stream1 ;
3111     delete stream2 ;
3112
3113     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3114}
3115
3116
3117TEST_F(basic_stl, simple_prog2) {
3118
3119    CBasicStl t1;
3120    CParserOption * po =&CGlobalInfo::m_options;
3121    po->preview.setVMode(7);
3122    po->preview.setFileWrite(true);
3123    po->out_file ="exp/stl_simple_prog2";
3124
3125     TrexStreamsCompiler compile;
3126
3127
3128     std::vector<TrexStream *> streams;
3129
3130     /* stream1 */
3131     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100);
3132     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3133     stream1->set_single_burst(5);
3134     stream1->m_enabled = true;
3135     stream1->m_self_start = true;
3136     stream1->m_next_stream_id=200;
3137
3138     CPcapLoader pcap;
3139     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3140     pcap.update_ip_src(0x10000001);
3141     pcap.clone_packet_into_stream(stream1);
3142
3143     streams.push_back(stream1);
3144
3145
3146     /* stream1 */
3147
3148     TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST, 0,200);
3149     stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3150     stream2->set_single_burst(5);
3151     stream2->m_isg_usec = 2000000; /*time betwean stream 1 to stream 2 */
3152     stream2->m_enabled = true;
3153     stream2->m_self_start = false;
3154
3155     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3156     pcap.update_ip_src(0x10000002);
3157     pcap.clone_packet_into_stream(stream2);
3158     streams.push_back(stream2);
3159
3160     uint8_t port_id = 0;
3161     std::vector<TrexStreamsCompiledObj *>objs;
3162     assert(compile.compile(port_id, streams, objs));
3163     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
3164
3165     t1.m_msg = lpstart;
3166
3167     bool res=t1.init();
3168
3169     delete stream1 ;
3170     delete stream2 ;
3171
3172     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3173}
3174
3175
3176
3177TEST_F(basic_stl, simple_prog1) {
3178
3179    CBasicStl t1;
3180    CParserOption * po =&CGlobalInfo::m_options;
3181    po->preview.setVMode(7);
3182    po->preview.setFileWrite(true);
3183    po->out_file ="exp/stl_simple_prog1";
3184
3185     TrexStreamsCompiler compile;
3186
3187
3188     std::vector<TrexStream *> streams;
3189
3190     /* stream1 */
3191     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100);
3192     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3193     stream1->set_single_burst(5);
3194     stream1->m_enabled = true;
3195     stream1->m_self_start = true;
3196     stream1->m_next_stream_id=200;
3197
3198     CPcapLoader pcap;
3199     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3200     pcap.update_ip_src(0x10000001);
3201     pcap.clone_packet_into_stream(stream1);
3202
3203     streams.push_back(stream1);
3204
3205
3206     /* stream1 */
3207
3208     TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST, 0,200);
3209     stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3210     stream2->set_single_burst(5);
3211     stream2->m_enabled = true;
3212     stream2->m_self_start = false;
3213
3214     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3215     pcap.update_ip_src(0x10000002);
3216     pcap.clone_packet_into_stream(stream2);
3217     streams.push_back(stream2);
3218
3219
3220     uint8_t port_id = 0;
3221     std::vector<TrexStreamsCompiledObj *>objs;
3222     assert(compile.compile(port_id, streams, objs));
3223     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
3224
3225
3226     t1.m_msg = lpstart;
3227
3228     bool res=t1.init();
3229
3230     delete stream1 ;
3231     delete stream2 ;
3232
3233     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3234}
3235
3236
3237
3238TEST_F(basic_stl, single_pkt_burst1) {
3239
3240    CBasicStl t1;
3241    CParserOption * po =&CGlobalInfo::m_options;
3242    po->preview.setVMode(7);
3243    po->preview.setFileWrite(true);
3244    po->out_file ="exp/stl_single_pkt_burst1";
3245
3246     TrexStreamsCompiler compile;
3247
3248
3249     std::vector<TrexStream *> streams;
3250
3251     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,0);
3252     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3253     stream1->set_single_burst(5);
3254     stream1->m_enabled = true;
3255     stream1->m_self_start = true;
3256
3257     CPcapLoader pcap;
3258     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3259     pcap.update_ip_src(0x10000001);
3260     pcap.clone_packet_into_stream(stream1);
3261
3262     streams.push_back(stream1);
3263
3264     uint8_t port_id = 0;
3265     std::vector<TrexStreamsCompiledObj *>objs;
3266     assert(compile.compile(port_id, streams, objs));
3267     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
3268
3269     t1.m_msg = lpstart;
3270
3271     bool res=t1.init();
3272
3273     delete stream1 ;
3274
3275     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3276}
3277
3278
3279
3280
3281
3282TEST_F(basic_stl, single_pkt) {
3283
3284    CBasicStl t1;
3285    CParserOption * po =&CGlobalInfo::m_options;
3286    po->preview.setVMode(7);
3287    po->preview.setFileWrite(true);
3288    po->out_file ="exp/stl_single_stream";
3289
3290     TrexStreamsCompiler compile;
3291
3292     uint8_t port_id=0;
3293
3294     std::vector<TrexStream *> streams;
3295
3296     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
3297     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3298
3299
3300     stream1->m_enabled = true;
3301     stream1->m_self_start = true;
3302     stream1->m_port_id= port_id;
3303
3304
3305     CPcapLoader pcap;
3306     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3307     pcap.update_ip_src(0x10000001);
3308     pcap.clone_packet_into_stream(stream1);
3309
3310     streams.push_back(stream1);
3311
3312     // stream - clean
3313
3314     std::vector<TrexStreamsCompiledObj *>objs;
3315     assert(compile.compile(port_id, streams, objs));
3316     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
3317
3318
3319     t1.m_msg = lpstart;
3320
3321     bool res=t1.init();
3322
3323     delete stream1 ;
3324
3325     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3326}
3327
3328void test_mac_replace(bool replace_src_by_pkt,
3329                      int replace_dst_mode,
3330                      std::string file){
3331    CBasicStl t1;
3332    CParserOption * po =&CGlobalInfo::m_options;
3333    po->preview.setVMode(7);
3334    po->preview.setFileWrite(true);
3335    po->out_file = file;
3336
3337     TrexStreamsCompiler compile;
3338
3339     uint8_t port_id=0;
3340
3341     std::vector<TrexStream *> streams;
3342
3343     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
3344     stream1->set_override_src_mac_by_pkt_data(replace_src_by_pkt);
3345     stream1->set_override_dst_mac_mode((TrexStream::stream_dst_mac_t)replace_dst_mode);
3346
3347     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3348
3349
3350     stream1->m_enabled = true;
3351     stream1->m_self_start = true;
3352     stream1->m_port_id= port_id;
3353
3354
3355     CPcapLoader pcap;
3356     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3357     pcap.update_ip_src(0x10000001);
3358     pcap.clone_packet_into_stream(stream1);
3359
3360     streams.push_back(stream1);
3361
3362     // stream - clean
3363
3364     std::vector<TrexStreamsCompiledObj *>objs;
3365     assert(compile.compile(port_id, streams, objs));
3366     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
3367
3368
3369     t1.m_msg = lpstart;
3370
3371     bool res=t1.init();
3372
3373     delete stream1 ;
3374
3375     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3376}
3377
3378TEST_F(basic_stl, single_pkt_mac0) {
3379
3380    test_mac_replace(false,
3381                     TrexStream::stCFG_FILE,
3382                     "exp/stl_single_stream_mac0");
3383}
3384
3385TEST_F(basic_stl, single_pkt_mac11) {
3386
3387    test_mac_replace(true,
3388                     TrexStream::stPKT,
3389                     "exp/stl_single_stream_mac11");
3390}
3391
3392TEST_F(basic_stl, single_pkt_mac10) {
3393
3394    test_mac_replace(false,
3395                     TrexStream::stPKT,
3396                     "exp/stl_single_stream_mac01");
3397}
3398
3399TEST_F(basic_stl, single_pkt_mac01) {
3400
3401    test_mac_replace(true,
3402                     TrexStream::stCFG_FILE,
3403                     "exp/stl_single_stream_mac10");
3404}
3405
3406
3407TEST_F(basic_stl, multi_pkt1) {
3408
3409    CBasicStl t1;
3410    CParserOption * po =&CGlobalInfo::m_options;
3411    po->preview.setVMode(7);
3412    po->preview.setFileWrite(true);
3413    po->out_file ="exp/stl_multi_pkt1";
3414
3415     TrexStreamsCompiler compile;
3416
3417
3418     std::vector<TrexStream *> streams;
3419
3420     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
3421     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3422
3423
3424     stream1->m_enabled = true;
3425     stream1->m_self_start = true;
3426
3427     CPcapLoader pcap;
3428     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3429     pcap.update_ip_src(0x10000001);
3430     pcap.clone_packet_into_stream(stream1);
3431
3432     streams.push_back(stream1);
3433
3434     TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,1);
3435     stream2->set_rate(TrexStreamRate::RATE_PPS,2.0);
3436
3437     stream2->m_enabled = true;
3438     stream2->m_self_start = true;
3439     stream2->m_isg_usec = 1000.0; /* 1 msec */
3440     pcap.update_ip_src(0x20000001);
3441     pcap.clone_packet_into_stream(stream2);
3442
3443     streams.push_back(stream2);
3444
3445
3446     // stream - clean
3447     uint8_t port_id = 0;
3448     std::vector<TrexStreamsCompiledObj *>objs;
3449     assert(compile.compile(port_id, streams, objs));
3450     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
3451
3452     t1.m_msg = lpstart;
3453
3454     bool res=t1.init();
3455
3456     delete stream1 ;
3457     delete stream2 ;
3458
3459     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3460}
3461
3462
3463class CEnableVm {
3464public:
3465    void run(bool full_packet,double duration,uint16_t cache );
3466    CEnableVm() {
3467        m_pg_id = -1;
3468    }
3469public:
3470    std::string    m_input_packet; //"cap2/udp_64B.pcap"
3471    std::string    m_out_file;     //"exp/stl_vm_enable0";
3472    int32_t        m_pg_id; // if >= 0, pg_id for flow stat testing
3473};
3474
3475void CEnableVm::run(bool full_packet,double duration=10.0,uint16_t cache=0){
3476    CFlowStatRuleMgr rule_mgr;
3477    CBasicStl t1;
3478    CParserOption * po =&CGlobalInfo::m_options;
3479    po->preview.setVMode(7);
3480    po->preview.setFileWrite(true);
3481    po->out_file =m_out_file;
3482
3483     TrexStreamsCompiler compile;
3484
3485     uint8_t port_id=0;
3486
3487     std::vector<TrexStream *> streams;
3488
3489     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
3490
3491     if ( cache ){
3492         stream1->m_cache_size=cache;
3493     }
3494
3495     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3496
3497     stream1->m_enabled = true;
3498     stream1->m_self_start = true;
3499     stream1->m_port_id= port_id;
3500
3501     CPcapLoader pcap;
3502     pcap.load_pcap_file(m_input_packet,0);
3503     pcap.update_ip_src(0x10000001);
3504     pcap.clone_packet_into_stream(stream1);
3505
3506     uint16_t pkt_size=pcap.m_raw.pkt_len;
3507
3508     vm_build_program_seq(stream1->m_vm,pkt_size, false);
3509#if 0
3510     if ( full_packet ){
3511         EXPECT_EQ(stream1->m_vm_prefix_size,pkt_size);
3512     }else{
3513         EXPECT_EQ(stream1->m_vm_prefix_size,35);
3514     }
3515#endif
3516
3517     if (m_pg_id >= 0) {
3518         stream1->m_rx_check.m_enabled = true;
3519         stream1->m_rx_check.m_rule_type = TrexPlatformApi::IF_STAT_PAYLOAD;
3520         stream1->m_rx_check.m_pg_id = m_pg_id;
3521         rule_mgr.init_stream(stream1); //different rule_mgr object, but we just want to init fields in stream
3522     } else {
3523         stream1->m_rx_check.m_enabled = false;
3524     }
3525
3526     streams.push_back(stream1);
3527
3528     // stream - clean
3529     std::vector<TrexStreamsCompiledObj *> objs;
3530
3531     assert(compile.compile(port_id,streams, objs) );
3532
3533     TrexStatelessDpStart * lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], duration /*sec */ );
3534
3535
3536     t1.m_msg = lpstart;
3537
3538     bool res=t1.init();
3539
3540     delete stream1 ;
3541
3542     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3543}
3544
3545TEST_F(basic_stl, vm_enable_cache_10) {
3546
3547    CEnableVm vm_test;
3548    vm_test.m_out_file = "exp/stl_vm_enable0_cache_10";
3549    vm_test.m_input_packet = "cap2/udp_64B.pcap";
3550    vm_test.run(true,10.0,100);
3551}
3552
3553TEST_F(basic_stl, vm_enable_cache_500) {
3554    /* multi mbuf cache */
3555    CEnableVm vm_test;
3556    vm_test.m_out_file = "exp/stl_vm_enable1_cache_500";
3557    vm_test.m_input_packet = "stl/yaml/udp_594B_no_crc.pcap";
3558    vm_test.run(false,20.0,19);
3559}
3560
3561
3562TEST_F(basic_stl, vm_enable0) {
3563
3564    CEnableVm vm_test;
3565    vm_test.m_out_file = "exp/stl_vm_enable0";
3566    vm_test.m_input_packet = "cap2/udp_64B.pcap";
3567    vm_test.run(true);
3568}
3569
3570#if 0
3571// todo: does not work with valgrind, because we need to free the dp->rx message queue in simulation mode
3572TEST_F(basic_stl, vm_enable0_flow_stat) {
3573
3574    CEnableVm vm_test;
3575    vm_test.m_out_file = "exp/stl_vm_enable0_flow_stat";
3576    vm_test.m_input_packet = "cap2/udp_64B.pcap";
3577    vm_test.m_pg_id = 5;
3578    vm_test.run(true);
3579}
3580#endif
3581
3582TEST_F(basic_stl, vm_enable1) {
3583
3584    CEnableVm vm_test;
3585    vm_test.m_out_file = "exp/stl_vm_enable1";
3586    vm_test.m_input_packet = "stl/yaml/udp_594B_no_crc.pcap";
3587    vm_test.run(false);
3588}
3589
3590#if 0
3591//todo: does not work. need to check
3592TEST_F(basic_stl, vm_enable1_flow_stat) {
3593
3594    CEnableVm vm_test;
3595    vm_test.m_out_file = "exp/stl_vm_enable1_flow_stat";
3596    vm_test.m_input_packet = "stl/yaml/udp_594B_no_crc.pcap";
3597    vm_test.m_pg_id = 5;
3598    vm_test.run(false);
3599}
3600#endif
3601
3602TEST_F(basic_stl, vm_enable2) {
3603
3604    CEnableVm vm_test;
3605    vm_test.m_out_file = "exp/stl_vm_enable2";
3606    vm_test.m_input_packet = "cap2/udp_64B.pcap";
3607    vm_test.run(true,50.0);
3608}
3609
3610
3611
3612
3613/* check disabled stream with multiplier of 5*/
3614TEST_F(basic_stl, multi_pkt2) {
3615
3616    CBasicStl t1;
3617    CParserOption * po =&CGlobalInfo::m_options;
3618    po->preview.setVMode(7);
3619    po->preview.setFileWrite(true);
3620    po->out_file ="exp/stl_multi_pkt2";
3621
3622     TrexStreamsCompiler compile;
3623
3624
3625     std::vector<TrexStream *> streams;
3626
3627
3628     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
3629     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3630
3631
3632     stream1->m_enabled = true;
3633     stream1->m_self_start = true;
3634
3635     CPcapLoader pcap;
3636     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3637     pcap.update_ip_src(0x10000001);
3638     pcap.clone_packet_into_stream(stream1);
3639
3640     streams.push_back(stream1);
3641
3642
3643     TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,1);
3644     stream2->set_rate(TrexStreamRate::RATE_PPS,2.0);
3645
3646     stream2->m_enabled = false;
3647     stream2->m_self_start = false;
3648     stream2->m_isg_usec = 1000.0; /* 1 msec */
3649     pcap.update_ip_src(0x20000001);
3650     pcap.clone_packet_into_stream(stream2);
3651
3652     streams.push_back(stream2);
3653
3654
3655     // stream - clean
3656     uint8_t port_id = 0;
3657     std::vector<TrexStreamsCompiledObj *>objs;
3658     assert(compile.compile(port_id, streams, objs, 1, 5.0));
3659     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
3660
3661     t1.m_msg = lpstart;
3662
3663     bool res=t1.init();
3664
3665     delete stream1 ;
3666     delete stream2 ;
3667
3668     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3669}
3670
3671
3672TEST_F(basic_stl, multi_burst1) {
3673
3674    CBasicStl t1;
3675    CParserOption * po =&CGlobalInfo::m_options;
3676    po->preview.setVMode(7);
3677    po->preview.setFileWrite(true);
3678    po->out_file ="exp/stl_multi_burst1";
3679
3680     TrexStreamsCompiler compile;
3681
3682
3683     std::vector<TrexStream *> streams;
3684
3685     TrexStream * stream1 = new TrexStream(TrexStream::stMULTI_BURST,0,0);
3686     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3687     stream1->set_multi_burst(5,
3688                              3,
3689                              2000000.0);
3690
3691     stream1->m_enabled = true;
3692     stream1->m_self_start = true;
3693
3694     CPcapLoader pcap;
3695     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3696     pcap.update_ip_src(0x10000001);
3697     pcap.clone_packet_into_stream(stream1);
3698
3699     streams.push_back(stream1);
3700
3701     uint8_t port_id = 0;
3702     std::vector<TrexStreamsCompiledObj *>objs;
3703     assert(compile.compile(port_id, streams, objs));
3704     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 40.0 /*sec */ );
3705
3706
3707     t1.m_msg = lpstart;
3708
3709     bool res=t1.init();
3710
3711     delete stream1 ;
3712
3713     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3714}
3715
3716/********************************************* Itay Tests Start *************************************/
3717
3718/**
3719 * check that continous stream does not point to another stream
3720 * (makes no sense)
3721 */
3722TEST_F(basic_stl, compile_bad_1) {
3723
3724     TrexStreamsCompiler compile;
3725     std::vector<TrexStream *> streams;
3726
3727     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,2);
3728     stream1->m_enabled = true;
3729     stream1->set_rate(TrexStreamRate::RATE_PPS,52.0);
3730     stream1->m_next_stream_id = 3;
3731
3732     streams.push_back(stream1);
3733
3734     std::string err_msg;
3735     std::vector<TrexStreamsCompiledObj *>objs;
3736     EXPECT_FALSE(compile.compile(0, streams, objs, 1, 1, &err_msg));
3737
3738     delete stream1;
3739
3740}
3741
3742/**
3743 * check for streams pointing to non exsistant streams
3744 *
3745 * @author imarom (16-Nov-15)
3746 */
3747TEST_F(basic_stl, compile_bad_2) {
3748
3749     TrexStreamsCompiler compile;
3750     std::vector<TrexStream *> streams;
3751
3752     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,1);
3753     stream1->m_enabled = true;
3754     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3755     stream1->set_single_burst(200);
3756
3757     /* non existant next stream */
3758     stream1->m_next_stream_id = 5;
3759
3760     TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,2);
3761     stream1->set_rate(TrexStreamRate::RATE_PPS,52.0);
3762
3763     streams.push_back(stream1);
3764     streams.push_back(stream2);
3765
3766
3767     uint8_t port_id = 0;
3768     std::string err_msg;
3769     std::vector<TrexStreamsCompiledObj *>objs;
3770     EXPECT_FALSE(compile.compile(port_id, streams, objs, 1, 1, &err_msg));
3771
3772
3773     delete stream1;
3774     delete stream2;
3775
3776}
3777
3778/**
3779 * check for "dead streams" in the mesh
3780 * a streams that cannot be reached
3781 *
3782 * @author imarom (16-Nov-15)
3783 */
3784TEST_F(basic_stl, compile_bad_3) {
3785
3786     TrexStreamsCompiler compile;
3787     std::vector<TrexStream *> streams;
3788     TrexStream *stream;
3789
3790     /* stream 1 */
3791     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 231);
3792     stream->m_enabled = true;
3793     stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3794     stream->set_single_burst(200);
3795
3796     stream->m_next_stream_id = 5481;
3797     stream->m_self_start = true;
3798
3799     streams.push_back(stream);
3800
3801     /* stream 2 */
3802     stream = new TrexStream(TrexStream::stCONTINUOUS, 0, 5481);
3803     stream->m_enabled = true;
3804     stream->m_next_stream_id = -1;
3805     stream->m_self_start = false;
3806     stream->set_rate(TrexStreamRate::RATE_PPS,52.0);
3807
3808     streams.push_back(stream);
3809
3810     /* stream 3 */
3811
3812     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1928);
3813     stream->m_enabled = true;
3814     stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3815     stream->set_single_burst(200);
3816
3817     stream->m_next_stream_id = -1;
3818     stream->m_self_start = true;
3819
3820     streams.push_back(stream);
3821
3822      /* stream 4 */
3823
3824     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 41231);
3825     stream->m_enabled = true;
3826     stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3827     stream->set_single_burst(200);
3828
3829     stream->m_next_stream_id = 3928;
3830     stream->m_self_start = false;
3831
3832     streams.push_back(stream);
3833
3834     /* stream 5 */
3835
3836     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 3928);
3837     stream->m_enabled = true;
3838     stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3839     stream->set_single_burst(200);
3840
3841     stream->m_next_stream_id = 41231;
3842     stream->m_self_start = false;
3843
3844     streams.push_back(stream);
3845
3846     /* compile */
3847     std::string err_msg;
3848     std::vector<TrexStreamsCompiledObj *>objs;
3849     EXPECT_FALSE(compile.compile(0, streams, objs, 1, 1, &err_msg));
3850
3851
3852     for (auto stream : streams) {
3853         delete stream;
3854     }
3855
3856}
3857
3858TEST_F(basic_stl, compile_with_warnings) {
3859
3860    TrexStreamsCompiler compile;
3861     std::vector<TrexStream *> streams;
3862     TrexStream *stream;
3863
3864     /* stream 1 */
3865     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 231);
3866     stream->m_enabled = true;
3867     stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3868     stream->set_single_burst(200);
3869
3870     stream->m_next_stream_id = 1928;
3871     stream->m_self_start = true;
3872
3873     streams.push_back(stream);
3874
3875     /* stream 2 */
3876     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 5481);
3877     stream->m_enabled = true;
3878     stream->m_next_stream_id = 1928;
3879     stream->m_self_start = true;
3880     stream->set_rate(TrexStreamRate::RATE_PPS,52.0);
3881
3882     streams.push_back(stream);
3883
3884     /* stream 3 */
3885
3886     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1928);
3887     stream->m_enabled = true;
3888     stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3889     stream->set_single_burst(200);
3890
3891     stream->m_next_stream_id = -1;
3892     stream->m_self_start = true;
3893
3894     streams.push_back(stream);
3895
3896
3897
3898     /* compile */
3899     std::string err_msg;
3900     std::vector<TrexStreamsCompiledObj *>objs;
3901     EXPECT_TRUE(compile.compile(0, streams, objs, 1, 1, &err_msg));
3902     delete objs[0];
3903
3904     EXPECT_TRUE(compile.get_last_compile_warnings().size() == 1);
3905
3906     for (auto stream : streams) {
3907         delete stream;
3908     }
3909
3910}
3911
3912
3913TEST_F(basic_stl, compile_good_stream_id_compres) {
3914
3915     TrexStreamsCompiler compile;
3916     std::vector<TrexStream *> streams;
3917
3918     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,700);
3919     stream1->m_self_start = true;
3920     stream1->m_enabled = true;
3921     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3922     stream1->set_single_burst(200);
3923
3924     /* non existant next stream */
3925     stream1->m_next_stream_id = 800;
3926
3927
3928     TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST,0,800);
3929     stream2->set_rate(TrexStreamRate::RATE_PPS,52.0);
3930     stream2->m_enabled = true;
3931     stream2->m_next_stream_id = 700;
3932     stream2->set_single_burst(300);
3933
3934
3935     streams.push_back(stream1);
3936     streams.push_back(stream2);
3937
3938     uint8_t port_id = 0;
3939     std::string err_msg;
3940     std::vector<TrexStreamsCompiledObj *>objs;
3941     EXPECT_TRUE(compile.compile(port_id, streams, objs, 1, 1, &err_msg));
3942
3943     printf(" %s \n",err_msg.c_str());
3944
3945     objs[0]->Dump(stdout);
3946
3947     EXPECT_EQ_UINT32(objs[0]->get_objects()[0].m_stream->m_stream_id,0);
3948     EXPECT_EQ_UINT32(objs[0]->get_objects()[0].m_stream->m_next_stream_id,1);
3949
3950     EXPECT_EQ_UINT32(objs[0]->get_objects()[1].m_stream->m_stream_id,1);
3951     EXPECT_EQ_UINT32(objs[0]->get_objects()[1].m_stream->m_next_stream_id,0);
3952
3953     delete objs[0];
3954
3955     delete stream1;
3956     delete stream2;
3957
3958}
3959
3960
3961
3962class DpToCpHandlerStopEvent: public DpToCpHandler {
3963public:
3964    DpToCpHandlerStopEvent(int event_id) {
3965        m_event_id = event_id;
3966    }
3967
3968    virtual void handle(TrexStatelessDpToCpMsgBase *msg) {
3969        /* first the message must be an event */
3970        TrexDpPortEventMsg *event = dynamic_cast<TrexDpPortEventMsg *>(msg);
3971        EXPECT_TRUE(event != NULL);
3972
3973        EXPECT_TRUE(event->get_event_id() == m_event_id);
3974        EXPECT_TRUE(event->get_port_id() == 0);
3975
3976    }
3977
3978private:
3979    int m_event_id;
3980};
3981
3982TEST_F(basic_stl, dp_stop_event) {
3983
3984    CBasicStl t1;
3985    CParserOption * po =&CGlobalInfo::m_options;
3986    po->preview.setVMode(7);
3987    po->preview.setFileWrite(true);
3988    po->out_file ="exp/ignore";
3989
3990    TrexStreamsCompiler compile;
3991
3992     uint8_t port_id=0;
3993
3994     std::vector<TrexStream *> streams;
3995
3996     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,0);
3997     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3998     stream1->set_single_burst(100);
3999
4000     stream1->m_enabled = true;
4001     stream1->m_self_start = true;
4002     stream1->m_port_id= port_id;
4003
4004
4005     CPcapLoader pcap;
4006     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
4007     pcap.update_ip_src(0x10000001);
4008     pcap.clone_packet_into_stream(stream1);
4009
4010     streams.push_back(stream1);
4011
4012     // stream - clean
4013
4014     std::vector<TrexStreamsCompiledObj *>objs;
4015     assert(compile.compile(port_id, streams, objs));
4016     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 17, objs[0], 10.0 /*sec */ );
4017
4018
4019     t1.m_msg = lpStartCmd;
4020
4021     /* let me handle these */
4022     DpToCpHandlerStopEvent handler(17);
4023     t1.m_dp_to_cp_handler = &handler;
4024
4025     bool res=t1.init();
4026     EXPECT_EQ_UINT32(1, res?1:0);
4027
4028     delete stream1 ;
4029
4030}
4031
4032TEST_F(basic_stl, graph_generator1) {
4033    std::vector<TrexStream *> streams;
4034    TrexStreamsGraph graph;
4035    TrexStream *stream;
4036
4037     /* stream 1 */
4038     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1);
4039     stream->m_enabled = true;
4040     stream->m_self_start = true;
4041
4042     stream->m_isg_usec = 42;
4043     stream->set_rate(TrexStreamRate::RATE_PPS,10);
4044     stream->set_single_burst(43281);
4045     stream->m_pkt.len = 512;
4046
4047     stream->m_next_stream_id = 2;
4048
4049
4050     streams.push_back(stream);
4051
4052     /* stream 2 */
4053     stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 2);
4054     stream->m_enabled = true;
4055     stream->m_self_start = false;
4056
4057     stream->set_rate(TrexStreamRate::RATE_PPS,20);
4058     stream->set_multi_burst(4918, 13, 7);
4059     stream->m_next_stream_id = -1;
4060     stream->m_pkt.len = 64;
4061
4062     streams.push_back(stream);
4063
4064     /* stream 3 */
4065     stream = new TrexStream(TrexStream::stCONTINUOUS, 0, 3);
4066     stream->m_enabled = true;
4067     stream->m_self_start = true;
4068
4069     stream->m_isg_usec = 50;
4070     stream->set_rate(TrexStreamRate::RATE_PPS,30);
4071     stream->m_next_stream_id = -1;
4072     stream->m_pkt.len = 1512;
4073
4074     streams.push_back(stream);
4075
4076
4077     const TrexStreamsGraphObj *obj = graph.generate(streams);
4078     EXPECT_EQ(obj->get_max_bps_l2(), 405120);
4079     EXPECT_EQ(obj->get_max_pps(), 50);
4080
4081     for (auto stream : streams) {
4082         delete stream;
4083     }
4084
4085     delete obj;
4086}
4087
4088
4089TEST_F(basic_stl, graph_generator2) {
4090    std::vector<TrexStream *> streams;
4091    TrexStreamsGraph graph;
4092    TrexStream *stream;
4093
4094    /* add some multi burst streams */
4095    stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 1);
4096    stream->m_enabled = true;
4097    stream->m_self_start = true;
4098
4099
4100    stream->set_rate(TrexStreamRate::RATE_PPS,1000);
4101
4102    /* a burst of 2000 packets with a delay of 1 second */
4103    stream->m_isg_usec = 0;
4104    stream->set_multi_burst(1000, 500, 1000 * 1000);
4105    stream->m_pkt.len = 64;
4106
4107    stream->m_next_stream_id = -1;
4108
4109    streams.push_back(stream);
4110
4111    /* another multi burst stream but with a shorter burst ( less 2 ms ) and
4112       higher ibg (2 ms) , one milli for each side
4113     */
4114    stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 2);
4115    stream->m_enabled = true;
4116    stream->m_self_start = true;
4117
4118    stream->set_rate(TrexStreamRate::RATE_PPS,1000);
4119    stream->m_isg_usec = 1000 * 1000 + 1000;
4120    stream->set_multi_burst(1000 - 2, 1000, 1000 * 1000 + 2000);
4121    stream->m_pkt.len = 128;
4122
4123    stream->m_next_stream_id = -1;
4124
4125    streams.push_back(stream);
4126
4127    const TrexStreamsGraphObj *obj = graph.generate(streams);
4128    EXPECT_EQ(obj->get_max_pps(), 1000.0);
4129
4130    EXPECT_EQ(obj->get_max_bps_l2(), (1000 * (128 + 4) * 8));
4131
4132
4133    for (auto stream : streams) {
4134        delete stream;
4135    }
4136
4137    delete obj;
4138}
4139
4140class VmSplitTest {
4141
4142public:
4143
4144    VmSplitTest(const char *erf_filename) {
4145        m_erf_filename = erf_filename;
4146        m_stream = NULL;
4147
4148        pcap.load_pcap_file("cap2/udp_64B.pcap",0);
4149        pcap.update_ip_src(0x10000001);
4150
4151    }
4152
4153    ~VmSplitTest() {
4154    }
4155
4156    void set_stream(TrexStream *stream) {
4157
4158        if (m_stream) {
4159            delete m_stream;
4160            m_stream = NULL;
4161        }
4162
4163        m_stream = stream;
4164        m_stream->m_enabled = true;
4165        m_stream->m_self_start = true;
4166
4167        pcap.clone_packet_into_stream(stream);
4168    }
4169
4170    void set_flow_var_as_split(StreamVmInstructionFlowMan::flow_var_op_e op,
4171                               uint64_t start,
4172                               uint64_t end,
4173                               uint64_t init) {
4174
4175        assert(m_stream);
4176
4177        StreamVmInstructionVar *split_instr = new StreamVmInstructionFlowMan("var1",
4178                                                                             8,
4179                                                                             op,
4180                                                                             init,
4181                                                                             start,
4182                                                                             end);
4183
4184        StreamVm &vm = m_stream->m_vm;
4185
4186        vm.add_instruction(split_instr);
4187
4188        vm.add_instruction(new StreamVmInstructionWriteToPkt( "var1", 60 - 8 - 4, 0,true));
4189
4190        vm.add_instruction(new StreamVmInstructionFixChecksumIpv4(14));
4191
4192    }
4193
4194    void set_client_var_as_split(uint32_t client_min_value,
4195                                 uint32_t client_max_value,
4196                                 uint16_t port_min,
4197                                 uint16_t port_max) {
4198
4199
4200        assert(m_stream);
4201
4202        StreamVmInstructionVar *split_instr = new StreamVmInstructionFlowClient("var1",
4203                                                                                client_min_value,
4204                                                                                client_max_value,
4205                                                                                port_min,
4206                                                                                port_max,
4207                                                                                0,
4208                                                                                0);
4209
4210
4211        StreamVm &vm = m_stream->m_vm;
4212
4213        vm.add_instruction(split_instr);
4214
4215        /* src ip */
4216        vm.add_instruction(new StreamVmInstructionWriteToPkt( "var1.ip",26, 0,true));
4217        vm.add_instruction(new StreamVmInstructionFixChecksumIpv4(14));
4218
4219        /* src port */
4220        vm.add_instruction(new StreamVmInstructionWriteToPkt("var1.port",34, 0,true));
4221    }
4222
4223    void run(uint8_t dp_core_count, uint8_t dp_core_to_check) {
4224        TrexStreamsCompiler compile;
4225        std::vector<TrexStreamsCompiledObj *> objs;
4226        std::vector<TrexStream *> streams;
4227
4228        if (m_stream->m_vm.is_vm_empty()) {
4229            set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,
4230                                  0,
4231                                  1000,
4232                                  0);
4233        }
4234
4235        streams.push_back(m_stream);
4236
4237        /* compiling for 8 cores */
4238        assert(compile.compile(0, streams, objs, dp_core_count));
4239
4240        /* choose one DP object */
4241        assert(objs[dp_core_to_check]);
4242
4243        TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(0, 0, objs[dp_core_to_check], 1 /*sec */ );
4244        objs[dp_core_to_check] = NULL;
4245        /* free all the non used DP objects */
4246        for (auto obj : objs) {
4247            if (obj) {
4248                delete obj;
4249            }
4250        }
4251
4252
4253        CParserOption * po =&CGlobalInfo::m_options;
4254        po->preview.setVMode(7);
4255        po->preview.setFileWrite(true);
4256        po->out_file = m_erf_filename;
4257
4258        CBasicStl t1;
4259        t1.m_msg = lpStartCmd;
4260        bool res=t1.init();
4261        EXPECT_EQ_UINT32(1, res?1:0);
4262
4263    }
4264
4265private:
4266    const char *m_erf_filename;
4267    TrexStream *m_stream;
4268    CPcapLoader pcap;
4269};
4270
4271
4272
4273TEST_F(basic_stl, vm_split_flow_var_inc) {
4274
4275    VmSplitTest split("exp/stl_vm_split_flow_var_inc.erf");
4276
4277    TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
4278    stream.set_single_burst(1000);
4279    stream.set_rate(TrexStreamRate::RATE_PPS,100000);
4280
4281    split.set_stream(&stream);
4282    split.run(8, 4);
4283
4284}
4285
4286TEST_F(basic_stl, vm_split_flow_var_small_range) {
4287    /* small range */
4288    VmSplitTest split("exp/stl_vm_split_flow_var_small_range.erf");
4289
4290    TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
4291    stream.set_single_burst(1000);
4292    stream.set_rate(TrexStreamRate::RATE_PPS,100000);
4293
4294    split.set_stream(&stream);
4295    split.set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_INC, 0, 1, 0);
4296
4297    split.run(8, 4);
4298
4299}
4300
4301TEST_F(basic_stl, vm_split_flow_var_big_range) {
4302    VmSplitTest split("exp/stl_vm_split_flow_var_big_range.erf");
4303
4304    TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
4305    stream.set_single_burst(1000);
4306    stream.set_rate(TrexStreamRate::RATE_PPS,100000);
4307
4308    split.set_stream(&stream);
4309    split.set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC, 1, 1000, 1000);
4310
4311    split.run(8, 7);
4312
4313
4314}
4315
4316TEST_F(basic_stl, vm_split_client_var) {
4317     VmSplitTest split("exp/stl_vm_split_client_var.erf");
4318
4319    TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
4320    stream.set_single_burst(1000);
4321    stream.set_rate(TrexStreamRate::RATE_PPS,100000);
4322
4323    split.set_stream(&stream);
4324    split.set_client_var_as_split(0x10000001, 0x100000fe, 5000, 5050);
4325
4326    split.run(8, 7);
4327
4328
4329}
4330
4331TEST_F(basic_stl, pcap_remote_basic) {
4332
4333    CBasicStl t1;
4334    CParserOption * po =&CGlobalInfo::m_options;
4335    po->preview.setVMode(7);
4336    po->preview.setFileWrite(true);
4337    po->out_file ="exp/pcap_remote_basic";
4338
4339    TrexStatelessCpToDpMsgBase *push_msg = new TrexStatelessDpPushPCAP(0,
4340                                                                       0,
4341                                                                       "exp/remote_test.cap",
4342                                                                       10,
4343                                                                       0,
4344                                                                       1,
4345                                                                       1,
4346                                                                       -1,
4347                                                                       false);
4348    t1.m_msg = push_msg;
4349
4350
4351    bool res = t1.init();
4352    EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
4353}
4354
4355TEST_F(basic_stl, pcap_remote_loop) {
4356
4357    CBasicStl t1;
4358    CParserOption * po =&CGlobalInfo::m_options;
4359    po->preview.setVMode(7);
4360    po->preview.setFileWrite(true);
4361    po->out_file ="exp/pcap_remote_loop";
4362
4363    TrexStatelessCpToDpMsgBase *push_msg = new TrexStatelessDpPushPCAP(0,
4364                                                                       0,
4365                                                                       "exp/remote_test.cap",
4366                                                                       1,
4367                                                                       0,
4368                                                                       1,
4369                                                                       3,
4370                                                                       -1,
4371                                                                       false);
4372    t1.m_msg = push_msg;
4373
4374    bool res = t1.init();
4375    EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
4376}
4377
4378TEST_F(basic_stl, pcap_remote_duration) {
4379
4380    CBasicStl t1;
4381    CParserOption * po =&CGlobalInfo::m_options;
4382    po->preview.setVMode(7);
4383    po->preview.setFileWrite(true);
4384    po->out_file ="exp/pcap_remote_duration";
4385
4386    TrexStatelessCpToDpMsgBase *push_msg = new TrexStatelessDpPushPCAP(0,
4387                                                                       0,
4388                                                                       "exp/remote_test.cap",
4389                                                                       100000,
4390                                                                       0,
4391                                                                       1,
4392                                                                       0,
4393                                                                       0.5,
4394                                                                       false);
4395    t1.m_msg = push_msg;
4396
4397    bool res = t1.init();
4398    EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
4399}
4400
4401TEST_F(basic_stl, pcap_remote_dual) {
4402
4403    CBasicStl t1;
4404    CParserOption * po =&CGlobalInfo::m_options;
4405    po->preview.setVMode(7);
4406    po->preview.setFileWrite(true);
4407    po->out_file ="exp/pcap_remote_dual";
4408
4409    TrexStatelessCpToDpMsgBase *push_msg = new TrexStatelessDpPushPCAP(0,
4410                                                                       0,
4411                                                                       "exp/remote_test_dual.erf",
4412                                                                       10000,
4413                                                                       0,
4414                                                                       1,
4415                                                                       0,
4416                                                                       0.5,
4417                                                                       true);
4418    t1.m_msg = push_msg;
4419
4420    bool res = t1.init();
4421    EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
4422}
4423
4424/********************************************* Itay Tests End *************************************/
4425class flow_stat_pkt_parse  : public testing::Test {
4426    protected:
4427     virtual void SetUp() {
4428     }
4429     virtual void TearDown() {
4430     }
4431   public:
4432};
4433
4434
4435TEST_F(flow_stat_pkt_parse, parser) {
4436    CFlowStatParserTest parser;
4437
4438    parser.test();
4439}
4440
4441class flow_stat  : public testing::Test {
4442    protected:
4443     virtual void SetUp() {
4444     }
4445     virtual void TearDown() {
4446     }
4447   public:
4448};
4449
4450
4451static const uint8_t TEST_L4_PROTO = IPPROTO_TCP;
4452
4453TEST_F(flow_stat, add_del_stream) {
4454    CFlowStatRuleMgr rule_mgr;
4455    uint8_t test_pkt[] = {
4456        // ether header
4457        0x74, 0xa2, 0xe6, 0xd5, 0x39, 0x25,
4458        0xa0, 0x36, 0x9f, 0x38, 0xa4, 0x02,
4459        0x81, 0x00,
4460        0x0a, 0xbc, 0x08, 0x00, // vlan
4461        // IP header
4462        0x45,0x02,0x00,0x30,
4463        0x01,0x02,0x40,0x00,
4464        0xff, TEST_L4_PROTO, 0xbd,0x04,
4465        0x10,0x0,0x0,0x1,
4466        0x30,0x0,0x0,0x1,
4467        // TCP heaader
4468        0xab, 0xcd, 0x00, 0x80, // src, dst ports
4469        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // seq num, ack num
4470        0x50, 0x00, 0xff, 0xff, // Header size, flags, window size
4471        0x00, 0x00, 0x00, 0x00, // checksum ,urgent pointer
4472        // some extra bytes
4473        0x1, 0x2, 0x3, 0x4
4474    };
4475
4476    TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
4477    TrexStream stream2(TrexStream::stSINGLE_BURST, 0, 0);
4478    TrexStream stream3(TrexStream::stSINGLE_BURST, 0, 0);
4479
4480    stream.m_rx_check.m_enabled = true;
4481
4482    stream.m_rx_check.m_rule_type = 7;
4483    stream.m_rx_check.m_pg_id = 5;
4484    stream.m_pkt.binary = (uint8_t *)test_pkt;
4485    stream.m_pkt.len = sizeof(test_pkt);
4486
4487    rule_mgr.init_stream(&stream);
4488
4489    try {
4490        rule_mgr.del_stream(&stream);
4491    } catch (TrexFStatEx e) {
4492        assert(e.type() == TrexException::T_FLOW_STAT_NO_STREAMS_EXIST);
4493    }
4494
4495    try {
4496        rule_mgr.add_stream(&stream);
4497    } catch (TrexFStatEx e) {
4498        assert(e.type() == TrexException::T_FLOW_STAT_BAD_RULE_TYPE);
4499    }
4500
4501    stream.m_rx_check.m_rule_type = TrexPlatformApi::IF_STAT_PAYLOAD;
4502    try {
4503        rule_mgr.add_stream(&stream);
4504    } catch (TrexFStatEx e) {
4505        assert(e.type() == TrexException::T_FLOW_STAT_PAYLOAD_TOO_SHORT);
4506    }
4507
4508    // change to UDP packet so it will be fine to work with
4509    test_pkt[27] = IPPROTO_UDP;
4510    int ret = rule_mgr.add_stream(&stream);
4511    assert (ret == 0);
4512
4513    stream3.m_rx_check.m_enabled = true;
4514    stream3.m_rx_check.m_rule_type = TrexPlatformApi::IF_STAT_PAYLOAD;
4515    stream3.m_rx_check.m_pg_id = 5; // same as first stream
4516    stream3.m_pkt.binary = (uint8_t *)test_pkt;
4517    stream3.m_pkt.len = sizeof(test_pkt);
4518    try {
4519        ret = rule_mgr.add_stream(&stream3);
4520    } catch (TrexFStatEx e) {
4521        assert(e.type() == TrexException::T_FLOW_STAT_DUP_PG_ID);
4522    }
4523
4524    ret = rule_mgr.del_stream(&stream);
4525    assert (ret == 0);
4526
4527    stream2.m_rx_check.m_enabled = true;
4528    stream2.m_rx_check.m_rule_type = TrexPlatformApi::IF_STAT_IPV4_ID;
4529    stream2.m_rx_check.m_pg_id = 5; // same as first stream
4530    stream2.m_pkt.binary = (uint8_t *)test_pkt;
4531    stream2.m_pkt.len = sizeof(test_pkt);
4532    ret = rule_mgr.add_stream(&stream2);
4533    assert (ret == 0);
4534
4535    ret = rule_mgr.del_stream(&stream2);
4536    assert (ret == 0);
4537    try {
4538        rule_mgr.del_stream(&stream2);
4539    } catch (TrexFStatEx e) {
4540        assert(e.type() == TrexException::T_FLOW_STAT_DEL_NON_EXIST);
4541    }
4542
4543    // do not want the destructor to try to free it
4544    stream.m_pkt.binary = NULL;
4545    stream2.m_pkt.binary = NULL;
4546    stream3.m_pkt.binary = NULL;
4547}
4548
4549TEST_F(flow_stat, alloc_mbuf_const) {
4550     CGenNodeStateless cg;
4551
4552     cg.alloc_flow_stat_mbuf_test_const();
4553}
4554