This is the initial commit.
[keystone-rtos/netapi.git] / ti / runtime / netapi / test / net_test.c
1 /******************************************
2  * File: net_test.c
3  * Purpose: test app for netapi
4  **************************************************************
5  * FILE:  net_test.c
6  * 
7  * DESCRIPTION:  netapi user space transport
8  *               library  test application
9  * 
10  * REVISION HISTORY:  rev 0.0.1 
11  *
12  *  Copyright (c) Texas Instruments Incorporated 2010-2011
13  * 
14  *  Redistribution and use in source and binary forms, with or without 
15  *  modification, are permitted provided that the following conditions 
16  *  are met:
17  *
18  *    Redistributions of source code must retain the above copyright 
19  *    notice, this list of conditions and the following disclaimer.
20  *
21  *    Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the 
23  *    documentation and/or other materials provided with the   
24  *    distribution.
25  *
26  *    Neither the name of Texas Instruments Incorporated nor the names of
27  *    its contributors may be used to endorse or promote products derived
28  *    from this software without specific prior written permission.
29  *
30  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
31  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
32  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
34  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
35  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
36  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
39  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
40  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  *****************************************/
44 #include "stdlib.h"
45 #include "stdio.h"
47 #include "trie.h"
48 #include "string.h"
49 #include "netapi.h"
50 #include "pktio.h"
51 #include <sys/resource.h>
53 /*************debug********************/
54 void dump_descr(unsigned long *p, int n)
55 {
56    printf("--------dump of descriptor %d %x\n", n, (int) p);
57    printf("> %x %x %x %x %x %x %x %x\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]);
58    printf("> %x %x %x %x %x %x %x %x\n",p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
59    printf("-----------------------------\n");
60 }
61 /*****************************************/
64 //************for multi pkt burst  xfer test in loopback mode
65 #define TX_BURST 4
66 int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;
68 //this device: 10.0.0.100, mac 0x,01,02,03,04,05  and .. 0x6
70 //test packet, setup for loopback (so dest is ourself)
71 static uint8_t testPkt[] = {
73   /* MAC header */
74   0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
75   0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04,
76   0x08, 0x00,
78   /* IP header */
79   0x45, 0x00,
80   0x00, 0x6c,  /* Length (including this header) */
81   0x00, 0x00, 0x00, 0x00, 0x05, 0x11,
82   0x00, 0x00,  /* Header checksum */
83   0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x64,
85   /* UDP header */
86   0x12, 0x34, 0x05, 0x55,
87   0x00, 0x58,  /* Length, including this header */
88   0x00, 0x00,  /* Header checksum */
90  /* Payload */
91   0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
92   0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
93   0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
94   0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
95   0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
96   0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,
97   0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
98   0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
99   0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
100   0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81
102 };
104 #define TEST_PAYLOAD_LEN            80
106 #define TEST_PKT_IP_OFFSET_BYTES        14
107 #define TEST_PKT_UDP_OFFSET_BYTES       34
108 #define TEST_PKT_PLOAD_OFFSET_BYTES     42
109 #define TEST_PKT_UDP_HDR_LEN            8
110 /* Offsets to length fields */
111 #define TEST_PKT_OFFSET_IP_LEN      16
112 #define TEST_PKT_OFFSET_UDP_LEN     38
114 #define TEST_PKT_LEN                122
116 /* The pseudo header checksum of the packet except for the 16 bit length */
117 #define TEST_PKT_PSEUDO_HDR_CHKSUM_SANS_LEN  0x0FFC
121 #if 1
122 //#include "arpa/inet.h"
123 long htonl(long x)
125         long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 |  (x&0xff)<<24 ;
126         return temp;
129 /********************************************************************
130  *  FUNCTION PURPOSE: Ones complement addition utility
131  ********************************************************************
132  ********************************************************************/
133 uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2)
135   uint32_t result;
137   result = (uint32_t)v1 + (uint32_t)v2;
138   result = (result >> 16) + (result & 0xffff);
139   result = (result >> 16) + (result & 0xffff);
141   return ((uint16_t)result);
144 /********************************************************************
145  *  FUNCTION PURPOSE: Ones complement checksum utility
146  ********************************************************************
147  ********************************************************************/
148  uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords)
150   uint16_t chksum = 0;
151   uint16_t v;
152   uint32_t i;
153   uint32_t j;
155   for (i = j = 0; i < nwords; i++, j+=2)  {
156     v = (p[j] << 8) | p[j+1];
157     chksum = test_utilOnesComplementAdd (chksum, v);
158   }
159   return (chksum);
160 } /* utilOnesCompChkSum */
162 /**************************************************************************************
163  * FUNCTION PURPOSE: Compute ipv4 psudo checksum
164  **************************************************************************************
165  * DESCRIPTION: Compute ipv4 psudo checksum
166  **************************************************************************************/
167 uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen)
169   uint16_t psudo_chksum;
171   psudo_chksum = test_utilOnesCompChkSum (&data[12], 4);
172   psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]);
173   psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen);
175   return (psudo_chksum);
177 } /* utilGetIpv4PsudoChkSum */
181 #endif
182 typedef struct stats_t
184         long itx;  //initially generated
185         long rx;
186         long tx;
187         long n_bad;
188         long n_new;
189 } STATS_T;
191 typedef struct head_t
193         long ip[5];
194         long udp[2];
195 } HEAD_T;
197 typedef struct key_t
199   long src_ip;
200   long dst_ip;
201   short src_port;
202   short dst_port;
203 } KEY_T;
205 unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0
206 unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1
207 nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
209 #if 1  //goes with real tx (to laptop) 
210 unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,
211                       0x00,0x01,0x02,0x03,0x04,0x05,
212                       0x08,0x00};
213 unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa};
214 #endif
216 #if 0  //goes with loopback
217 unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05, 
218                       0x00,0x11,0x22,0x33,0x44,0x55,
219                       0x08,0x00};
220 #endif
221 #define NE 65536 
222 HEAD_T *nat;
224 #define NP 5000
225 int n_pkt = NP;
226 STATS_T stats;
228 Trie * P_trie;
229 HEAD_T pkts[NP];
230 #define PERSLOW  10  //% of pkts that will not be fastpath'd 
231 int perslow= PERSLOW;
233 /*******************************************
234  *************NETAPI OBJECTS***************
235  *****************************************/
236 Pktlib_HeapHandle OurHeap;
237 PKTIO_HANDLE_T *our_chan;
238 PKTIO_HANDLE_T *netcp_rx_chan;
239 PKTIO_HANDLE_T *netcp_tx_chan;
240 PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
241 PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
242 PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
244 void house(NETAPI_SCHED_HANDLE_T *s);
245 NETAPI_T netapi_handle;
246 NETAPI_SCHED_HANDLE_T * our_sched;
247 NETAPI_SCHED_CONFIG_T our_sched_cfg={
248   NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 50  //every 50 poll loops
249 };
250 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
251 NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock; 
252 NETAPI_TIMER_T t1;
253 NETAPI_TIMER_T t2;
254 NETAPI_TIMER_T t3;
256 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
257         int n_fired,     //# timers fired
258         NETAPI_TIMER_LIST_T fired_list,
259         uint64_t currentTime);
261 /*************************END NETAPI OBJECTS***********************/
263 #define START_SRC_IP 0x0a00000a
264 #define DST_IP       0xc0a80001
265 #define NEW_START_SRC_IP 0x9eda000a
266 #define DST_PORT 0x555 
267 #define START_SRC_PORT 0x1234
268 #define NEW_START_SRC_PORT 100
269 void update_header(HEAD_T * p_head, int len)
271    unsigned char *p = (unsigned char *) &p_head->udp[1];
272    len -= (20+14);
273    /* update ip checksum */
274    /* update udp checksum */
275    /* update length */
276    *p= (len&0xff00)>>8;
277    *(p+1) = len&0xff;
280 void gen_pkts(int np)
282 int i;
283 int ip = START_SRC_IP &0xff;
284 int port= START_SRC_PORT;
285 HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP},
286              {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}};
287 /* endian convert header */
288 temp.ip[0]=htonl(temp.ip[0]);
289 temp.ip[1]=htonl(temp.ip[1]);
290 temp.ip[2]=htonl(temp.ip[2]);
291 temp.ip[3]=htonl(temp.ip[3]);
292 temp.ip[4]=htonl(temp.ip[4]);
293 temp.udp[0]=htonl(temp.udp[0]);
294 temp.udp[1]=htonl(temp.udp[1]);
296 for(i=0;(i<np) && (i<NP);i++)
297   {
298        memcpy(&pkts[i],&temp,sizeof(temp));
299        update_header(&pkts[i],512);      /* update checksums etc */
300        /* change template for new pkt */
301        ip+=1;
302        if(ip>254) {(ip=START_SRC_IP&0xff); port+=1; }
303        temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip);
304        temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port);
305        temp.udp[1] = htonl(temp.udp[1]);
306      
307   }
308   n_pkt=np;
310 void build_table(Trie * p_trie)
312 int i;
313 int sip=NEW_START_SRC_IP&0xff;
314 int sport=NEW_START_SRC_PORT; 
315 HEAD_T temp;
316 KEY_T key;
317 int skip;
318 int nskip=0;
319 for(i=0;(i<n_pkt) && (i<NE);i++)
321    skip = rand()%100;
322    if (skip<perslow) {nskip++;continue;}
323    memcpy(&temp,&pkts[i],sizeof(temp));
324    temp.ip[3]=htonl(((NEW_START_SRC_IP)&(0xffffff00))|(sip));
325    temp.udp[0] = htonl((temp.udp[0]&0xffff)| (sport<<16));
326    memcpy(&nat[i], &temp, sizeof(temp));
328    //insert entry
329    key.src_ip = pkts[i].ip[3];
330    key.dst_ip = pkts[i].ip[4];
331    key.src_port= (pkts[i].udp[0]&0xffff0000)>>16;
332    key.dst_port= (pkts[i].udp[0]&0x0000ffff);
333    trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[i]);
334    /* update */
335   sport+= 1;
336   if (sport > 60000) { sport = NEW_START_SRC_PORT; sip+=1; }
338  //printf("build tab: %d %d\n", n_pkt , nskip);
341 //===========stub transmitter==================
342 void send_pkt(Ti_Pkt *pkt, int len)
344 Pktlib_freePacket((Ti_Pkt*)pkt);
345         return;
349 void slow_path(Ti_Pkt *pkt, int len)
352          {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}
353 Pktlib_freePacket((Ti_Pkt*)pkt);
354         return;
356 /* check header */
357 int check_header(HEAD_T * p_head)
359  /* check version */
360  /* ip check sum */
361  /* udp check sum */
362  return 1;
365 #define PKT_LEN 1400
366 void test_alloc_free(int n)
368 int i;
369 Ti_Pkt * b;
371 for(i=0;i<n;i++)
373   b=Pktlib_allocPacket(OurHeap,PKT_LEN);
374   Pktlib_freePacket(b);
377 /*-----------test driver: gen an input pkt------- */
378 //char buffer[sizeof(HEAD_T)+PKT_LEN];
379 Ti_Pkt * get_pkt(int n, unsigned int *p_len)
381    int ind;
382    long long temp;
383    Ti_Pkt * b;
384    char * buffer;
385    unsigned int len;
387   if (pktloopback==0)
388   {
389         if (n>=4) return NULL;   //just gen pkts to warm swtich, so that it knows
390                                 //our mac is valid
391   }  
392   b=Pktlib_allocPacket(OurHeap,PKT_LEN);
393   if (!b) 
394     {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};
396    //debug
397    //printf("pkt= %x %x\n", b, Pktlib_getNextPacket(b));
399 #if 0
400 /*temp patch - should move inside nwal **/
402 Cppi_Desc * pHdrDesc = Pktlib_getDescFromPacket(b);
404 /* Initialize the PS for no control info.  */
405 Cppi_setPSLen (Cppi_DescType_HOST, (Cppi_Desc *)pHdrDesc, 0);
407 #endif
409     //debug - way to validate descriptor
410     {Ti_Pkt* k= Pktlib_getNextPacket(b); 
411          if(k != 0) {printf(" genpkt, nexpkt != NULL");}}
414    //get pointer to buffer area of packet
415    Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len);
417 #if 0 
418 if (pktloopback==0)
420    temp = (long long) rand();
421    temp *= PKT_LEN;
422    temp /= RAND_MAX;
423    temp +=2;
424    *p_len = (int) temp; 
425    *p_len = *p_len &0xfffffffe;
426    temp = (long long) rand();
427    temp *= n_pkt;
428    temp /= RAND_MAX;
429    ind = (int) temp;
430    update_header(&pkts[ind],*p_len);
431    //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len);
432     memcpy(&buffer[0], &mac_header[0],14);
433     memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T)); 
435 else
436 #endif
438    //copy test packet into buffer
440     memcpy(&buffer[0], &testPkt[0],TEST_PKT_LEN);
441     *p_len = TEST_PKT_LEN;
443     return b; 
447 /******************************************************/
448 /******************PKT RECEIVE HANDLER *************************/
449 /******************************************************/
450 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
451                          PKTIO_METADATA_T meta[], int n_pkts,
452                          uint64_t ts )
454 int i;
455 int len;
456 int p;
457 HEAD_T * p_res;
458 Ti_Pkt * tip;
459 unsigned int templen;
460 int err;
461 KEY_T key;
462 char * p_pkt;
463 HEAD_T * p_head;
464 HEAD_T temp_head;
466     p_head=&temp_head;
468     //debug
469 #if 0
470     if (n_pkts != TX_BURST) {
471       printf("recv_cb, txsofar=%d rxsofar=%d  np = %d, NOT %d\n", 
472              stats.itx, stats.rx, n_pkts,TX_BURST);
473       our_stats_cb(netapi_handle,NULL);
474     }
475 #endif
476     //test_alloc_free(7);
477     //printf("recv start\n");
479    /* loop over received pkts */
480    for(i=0;i<n_pkts;i++)
481    {
482         tip = p_recv[i];
483         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
484         len = Pktlib_getPacketLen(tip);//real length
486          //debug: validate descriptor */
487          if(Pktlib_getNextPacket(tip) != 0) {printf(" rcv_cb, nexpkt != NULL");}
488         //debug printf("recv pkt, len=%d %d\n", len, templen);
489         stats.rx+=1;
491 #ifdef DEBUG_DESC
492    if (stats.rx<16){printf(">rx dmp.."); dump_descr((long *) tip, stats.rx);}
493    else if (stats.rx>99) {printf(">rx dmp.."); dump_descr((long *) tip,stats.rx);}
494 #endif
497         /* check header */
498         memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
499         if (!check_header(p_head)) { 
500                 stats.n_bad+=1;Pktlib_freePacket(tip); continue;
501         }
503         /* lookup flow */
504         key.src_ip = p_head->ip[3];
505         key.dst_ip = p_head->ip[4];
506         key.src_port= (p_head->udp[0]&0xffff0000)>>16;
507         key.dst_port= (p_head->udp[0]&0x0000ffff);
508         p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key));
509         if (!p_res) { stats.n_new+=1;  slow_path(tip, len); continue;}
511         /* copy header */
512         memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T));
514         /* update checksums */
515         //update_header(p_head,len);
516         memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));
517         /* update_mac(&p_pkt[0]);  */
519         /* send pkt */
520         send_pkt(tip,len);
521         stats.tx+=1;
522     }
523     //printf("recv done\n");
526 //timer callback 
527 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
528         int n_fired,     //# timers fired
529         NETAPI_TIMER_LIST_T fired_list,
530         uint64_t currentTime)
532 int i;
533 NETAPI_TIMER_T tx;
534 int cookie;
535 int err;
536 unsigned long long et;
537 printf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);
538 tx = netapi_TimerGetFirst(fired_list);
539 for(i=0;i<n_fired;i++)
541   cookie = (int) netapi_TimerGetCookie(tx);
542   et =  netapi_TimerGetTs(tx); //debug
543   printf("   timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);
544   if (cookie ==1)
545      t1 = netapi_TimerGroupStartTimer(
546         th,
547         (void *) 1,
548         100LL,  //every  second
549         &err);
550   else if (cookie ==2)
551       t1 = netapi_TimerGroupStartTimer(
552         th,
553         (void *) 2,
554         200LL,  //every  second
555         &err);
556   else
557     t3 = netapi_TimerGroupStartTimer(
558         th,
559         (void *) 3,
560         300LL,  //every  second
561         &err);
564   tx = netapi_TimerGetNext(fired_list,tx); 
569 static int np2process = NP;
570 /******************************************************
571  * stats callback
572  *******************************************************/
573 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)
575 uint32_t numFreeDataPackets;
576 uint32_t numZeroBufferPackets;
577 uint32_t numPacketsinGarbage;
579 printf("stats @ %lld\n", netapi_getTimestamp());
580 if(pPaStats)
582        printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);
583        printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);
584        printf("C1 number llc/snap fail:        %d\n", pPaStats->classify1.nLlcSnapFail);
585        printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);
586        printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);
587        printf ("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);
588        printf("C1 number of command failures:  %d\n", pPaStats->classify1.nCommandFail);
589        printf("C1 number invalid reply dests:  %d\n", pPaStats->classify1.nInvalidComReplyDest);
590        printf ("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);
591        printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);
592        printf ("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);
593        printf ("C1 number of system fails:      %d\n\n",pPaStats->classify1.nSystemFail);
595 Pktlib_getHeapStats(OurHeap, &numFreeDataPackets,
596                              &numZeroBufferPackets, &numPacketsinGarbage);
597 printf("heap stats>  #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets,
598                                 numZeroBufferPackets, numPacketsinGarbage);
599 //debug
600 dump_poll_stats();
605 //******************************************************
606 //use scheduling housekeeping callback to generate pkts
607 //******************************************************
608 void house(NETAPI_SCHED_HANDLE_T * s)
610 Ti_Pkt * tip;
611 unsigned int len;
612 nwalTxPktInfo_t meta_tx={0};
613 PKTIO_METADATA_T meta = {PKTIO_META_TX,0};
614 int err;
615 static int house_pkts_gened=0;
616 int p;
617 unsigned char * pIpHdr,* pData;
619 for(p=0;p<TX_BURST;p++) {  
620 //reguest stats 
621 if ((house_pkts_gened>0) && (! (house_pkts_gened%400)) )
623    printf("net_test> request stats at n=%d \n",house_pkts_gened);
624    netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err); 
625    if (err!=0) {printf("stats req failed\n");}
629   if (house_pkts_gened >= np2process+ 100)
630   {
631      //shutdown
632      netapi_schedShutdown(s,NULL,&err);
633      continue;
634   }
636   else if (house_pkts_gened >= np2process) { house_pkts_gened+=1;  continue;}
637   
639 /* manufacture a pkt to transmit */
640    tip = get_pkt(house_pkts_gened, &len);
641    if(!tip) { house_pkts_gened +=1; continue; }
643    /* set the pkt length */
644    Pktlib_setPacketLen(tip, len);
646    /* set up meta data */
647     meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM);
648     meta_tx.startOffset = 0;
649     meta_tx.pktLen = len;
650     meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES;
651     meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES;
652     meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN;
653     meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;
654     meta_tx.ploadLen = TEST_PAYLOAD_LEN;
656     Pktlib_getDataBuffer(tip,&pData,&len);
657     pIpHdr = pData + meta_tx.ipOffBytes;
658     meta_tx.pseudoHdrChecksum =
659         test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));
661    /* post it to netcp tx channel*/
662    meta.u.tx_meta=&meta_tx;
663 #ifdef DEBUG_DESC
664    if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened);
665    else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened);
666 #endif
667    pktio_send(netcp_tx_chan,tip,&meta,&err);
668    if (err == 0) stats.itx +=1;
670    house_pkts_gened +=1;
671  }
675 /***************************************
676  ********** test driver*****************
677  ***************************************/
678 int main(int argc, char **argv)
680 int err;
681 rlim_t oss,ss = 1024*1024;
682 struct rlimit rl;
684 err= getrlimit(RLIMIT_STACK,&rl);
685 if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");
686 #if 0
687 rl.rlim_cur = ss;
688 err=setrlimit(RLIMIT_STACK,&rl);
689 if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");
690 #endif
692 if (argc>=2)  np2process = atoi(argv[1]);
693 if (np2process<0) np2process = NP; /* default */
694 if (argc==3)  perslow = atoi(argv[2]);
695 if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default
696 if (argc>3) {printf("net_test  <no of pkts to process> <percent slow path>\n"); exit(1);}
699 //real mode, so update our test packet mac header and ip header
700 if (pktloopback==0)
702 memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address
703 memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses
706 /*******************************************/
707 /*************NETAPI STARTUP****************/
708 /*******************************************/
710 /* create netapi */
711 netapi_handle = netapi_init(NETAPI_SYS_MASTER);
713 /* open the main heap */
714 OurHeap = Pktlib_findHeapByName("netapi");
715 if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}
717 /* create a pktio channel */
718 our_chan=pktio_create(netapi_handle,"our1stq",recv_cb, &our_chan_cfg,&err);
719 if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}
721 /* open netcp default tx, rx queues */
722 netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
723 if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}
724 netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, recv_cb, &netcp_rx_cfg,  &err);
725 if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
728 /* create scheduler instance */
729 our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
730 if (!our_sched) {printf("sched create failed\n"); exit(1);}
732 /* add mac intefaces */
733 netcp_cfgCreateMacInterface(
734                   netapi_handle,
735                   &mac0[0],
736                   0,0,
737                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
738                   (NETCP_CFG_VLAN_T ) NULL ,  //future
739                   1, 
740                   &err);
741 if (err) {printf("addmac0 failed %d\n",err); exit(1); } 
743 //attach an IP to this interface
744 netcp_addIp(
745                   netapi_handle,
746                   0,
747                   nwal_IPV4,
748                   &OurIp0,
749                   NULL,  //all IP
750                   (NETCP_CFG_ROUTE_HANDLE_T) NULL,
751                   &err
752                   );
753 if (err) {printf("addip0 failed %d\n",err); exit(1); } 
754 #if 1
755 //create a 2nd mac instance
756 netcp_cfgCreateMacInterface(
757                   netapi_handle,
758                   &mac1[0],
759                   1,1,
760                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
761                   (NETCP_CFG_VLAN_T ) NULL ,  //future
762                   1,
763                   &err);
764 if (err) {printf("addmac1 failed %d\n",err); exit(1); }
765 #endif
767  ourTimerBlock = netapi_TimerGroupCreate(
768         netapi_handle,
769         "our1sttimer",
770         our_timer_cb,
771         0,    //1 if timers local to thread
772         0,    //1 if expect to cancel
773         netapi_getTicksPerSec()/100,  /* 10 msc resolution for these timers */
774         100,
775         &err);
776 if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}
778 //start a couple of timers 
779 t1 = netapi_TimerGroupStartTimer(
780         ourTimerBlock,
781         (void *) 1,
782         100LL,  //every  second
783         &err);
784 if (err) {printf("timerstart failed %d\n");}
785 t2 = netapi_TimerGroupStartTimer(
786         ourTimerBlock,
787         (void *) 2,
788         200LL,  //every 1.1second
789         &err);
790 if (err) {printf("timerstart failed %d\n");}
791 t3 = netapi_TimerGroupStartTimer(
792         ourTimerBlock,
793         (void *) 3,
794         300LL,  //every 3 seconds
795         &err);
796 if (err) {printf("timerstart failed %d\n");}
799 /*********************************************/
800 /*****************end NETAPI STARTUP**********/
801 /*********************************************/
804 /********************************************
805 * Basic pkt loopback test
806 *********************************************/
809 /* create TRIE */
810 P_trie = trie_new();
811 if (!P_trie) {printf("trie alloc failed\n"); exit(1);}
813 nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T));
814 if (!nat) {printf("malloc of nat table failed\n"); exit(1);}
816 gen_pkts(np2process<NP ? np2process:NP);
818 /* build table */
819 build_table(P_trie);
822 /* processing loop: get pkt, check it, look up in table, copy new header,
823    send packet */
824 srand((unsigned) np2process);
827 /*********************************************/
828 /**************Entry point into scheduler ****/
829 /*********************************************/
830 netapi_schedWaitForEvents(our_sched, &err);
832 /* done */
833 printf("done: itx=%d rx=%d tx=%d bad=%d slow=%d\n",stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new);
834 our_stats_cb(netapi_handle, NULL);
836 netapi_shutdown(netapi_handle);