added docs dir
[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 <stdio.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <string.h>
50 #include "trie.h"
51 #include "string.h"
52 #include "netapi.h"
53 #include "pktio.h"
54 #include <sys/resource.h>
56 /*************debug********************/
57 void dump_descr(unsigned long *p, int n)
58 {
59    printf("--------dump of descriptor %d %x\n", n, (int) p);
60    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]);
61    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]);
62    printf("-----------------------------\n");
63 }
64 /*****************************************/
67 //************for multi pkt burst  xfer test in loopback mode
68 #define TX_BURST 4
69 int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;
71 //this device: 10.0.0.100, mac 0x,01,02,03,04,05  and .. 0x6
73 //test packet, setup for loopback (so dest is ourself)
74 static uint8_t testPkt[] = {
76   /* MAC header */
77   0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
78   0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04,
79   0x08, 0x00,
81   /* IP header */
82   0x45, 0x00,
83   0x00, 0x6c,  /* Length (including this header) */
84   0x00, 0x00, 0x00, 0x00, 0x05, 0x11,
85   0x00, 0x00,  /* Header checksum */
86   0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x64,
88   /* UDP header */
89   0x12, 0x34, 0x05, 0x55,
90   0x00, 0x58,  /* Length, including this header */
91   0x00, 0x00,  /* Header checksum */
93  /* Payload */
94   0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
95   0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
96   0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
97   0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
98   0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
99   0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,
100   0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
101   0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
102   0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
103   0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81
105 };
107 #define TEST_PAYLOAD_LEN            80
109 #define TEST_PKT_IP_OFFSET_BYTES        14
110 #define TEST_PKT_UDP_OFFSET_BYTES       34
111 #define TEST_PKT_PLOAD_OFFSET_BYTES     42
112 #define TEST_PKT_UDP_HDR_LEN            8
113 /* Offsets to length fields */
114 #define TEST_PKT_OFFSET_IP_LEN      16
115 #define TEST_PKT_OFFSET_UDP_LEN     38
117 #define TEST_PKT_LEN                122
119 /* The pseudo header checksum of the packet except for the 16 bit length */
120 #define TEST_PKT_PSEUDO_HDR_CHKSUM_SANS_LEN  0x0FFC
124 #if 1
125 //#include "arpa/inet.h"
126 long htonl(long x)
128         long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 |  (x&0xff)<<24 ;
129         return temp;
132 /********************************************************************
133  *  FUNCTION PURPOSE: Ones complement addition utility
134  ********************************************************************
135  ********************************************************************/
136 uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2)
138   uint32_t result;
140   result = (uint32_t)v1 + (uint32_t)v2;
141   result = (result >> 16) + (result & 0xffff);
142   result = (result >> 16) + (result & 0xffff);
144   return ((uint16_t)result);
147 /********************************************************************
148  *  FUNCTION PURPOSE: Ones complement checksum utility
149  ********************************************************************
150  ********************************************************************/
151  uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords)
153   uint16_t chksum = 0;
154   uint16_t v;
155   uint32_t i;
156   uint32_t j;
158   for (i = j = 0; i < nwords; i++, j+=2)  {
159     v = (p[j] << 8) | p[j+1];
160     chksum = test_utilOnesComplementAdd (chksum, v);
161   }
162   return (chksum);
163 } /* utilOnesCompChkSum */
165 /**************************************************************************************
166  * FUNCTION PURPOSE: Compute ipv4 psudo checksum
167  **************************************************************************************
168  * DESCRIPTION: Compute ipv4 psudo checksum
169  **************************************************************************************/
170 uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen)
172   uint16_t psudo_chksum;
174   psudo_chksum = test_utilOnesCompChkSum (&data[12], 4);
175   psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]);
176   psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen);
178   return (psudo_chksum);
180 } /* utilGetIpv4PsudoChkSum */
184 #endif
185 typedef struct stats_t
187         long itx;  //initially generated
188         long rx;
189         long tx;
190         long n_bad;
191         long n_new;
192 } STATS_T;
194 typedef struct head_t
196         long ip[5];
197         long udp[2];
198 } HEAD_T;
200 typedef struct key_t
202   long src_ip;
203   long dst_ip;
204   short src_port;
205   short dst_port;
206 } KEY_T;
208 unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0
209 unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1
210 nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
211 nwalIpAddr_t OurIp1={ 10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
213 #if 1  //goes with real tx (to laptop) 
214 unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,
215                       0x00,0x01,0x02,0x03,0x04,0x05,
216                       0x08,0x00};
217 unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa};
218 #endif
220 #if 0  //goes with loopback
221 unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05, 
222                       0x00,0x11,0x22,0x33,0x44,0x55,
223                       0x08,0x00};
224 #endif
225 #define NE 65536 
226 HEAD_T *nat;
228 #define NP 5000
229 int n_pkt = NP;
230 STATS_T stats;
232 Trie * P_trie;
233 HEAD_T pkts[NP];
234 #define PERSLOW  10  //% of pkts that will not be fastpath'd 
235 int perslow= PERSLOW;
237 /*******************************************
238  *************NETAPI OBJECTS***************
239  *****************************************/
240 Pktlib_HeapHandle OurHeap;
241 PKTIO_HANDLE_T *our_chan;
242 PKTIO_HANDLE_T *netcp_rx_chan;
243 PKTIO_HANDLE_T *netcp_tx_chan;
244 PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
245 PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
246 PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
248 void house(NETAPI_SCHED_HANDLE_T *s);
249 NETAPI_T netapi_handle;
250 NETAPI_SCHED_HANDLE_T * our_sched;
251 NETAPI_SCHED_CONFIG_T our_sched_cfg={
252   NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 50  //every 50 poll loops
253 };
254 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
255 NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock; 
256 NETAPI_TIMER_T t1;
257 NETAPI_TIMER_T t2;
258 NETAPI_TIMER_T t3;
260 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
261         int n_fired,     //# timers fired
262         NETAPI_TIMER_LIST_T fired_list,
263         uint64_t currentTime);
265 /*************************END NETAPI OBJECTS***********************/
267 #define START_SRC_IP 0x0a00000a
268 #define DST_IP       0xc0a80001
269 #define NEW_START_SRC_IP 0x9eda000a
270 #define DST_PORT 0x555 
271 #define START_SRC_PORT 0x1234
272 #define NEW_START_SRC_PORT 100
273 void update_header(HEAD_T * p_head, int len)
275    unsigned char *p = (unsigned char *) &p_head->udp[1];
276    len -= (20+14);
277    /* update ip checksum */
278    /* update udp checksum */
279    /* update length */
280    *p= (len&0xff00)>>8;
281    *(p+1) = len&0xff;
284 #if 0
285 void gen_pkts(int np)
287 int i;
288 int ip = START_SRC_IP &0xff;
289 int port= START_SRC_PORT;
290 //HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP},
291 //             {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}};
292 HEAD_T temp;
293 memcpy(&temp,&testPkt[0],sizeof(HEAD_T));
295 for(i=0;(i<np) && (i<NP);i++)
296   {
297        memcpy(&pkts[i],&temp,sizeof(temp));
298        update_header(&pkts[i],512);      /* update checksums etc */
299        /* change template for new pkt */
300        ip+=1;
301        if(ip>254) {(ip=START_SRC_IP&0xff); port+=1; }
302        temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip);
303        temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port);
304        temp.udp[1] = htonl(temp.udp[1]);
305      
306   }
307   n_pkt=np;
309 #endif
311 void build_table(Trie * p_trie)
313 int i;
314 int sport=NEW_START_SRC_PORT; 
315 HEAD_T temp,temp2;
316 KEY_T key;
318 memcpy(&temp,&testPkt[14],sizeof(temp));
320  //insert entry into trie
321 key.src_ip = temp.ip[3];
322 key.dst_ip = temp.ip[4];
323 key.src_port= (temp.udp[0]&0xffff0000)>>16;
324 key.dst_port= (temp.udp[0]&0x0000ffff);
325 trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[0]); //asociate with nat entry 0
327 //build nat table
328 for(i=0;i<100;i++)
330    memcpy(&temp2,&testPkt[14],sizeof(temp));
331    temp2.udp[0] = (temp2.udp[0] & 0xffff0000) |  sport;
332    memcpy(&nat[i], &temp2, sizeof(temp2));
333    sport+= 1;
337 //===========stub transmitter==================
338 void send_pkt(Ti_Pkt *pkt, int len)
340 //just free pkt.  Don't send
341 Pktlib_freePacket((Ti_Pkt*)pkt);
342         return;
345 //==========stub slow path============
346 void slow_path(Ti_Pkt *pkt, int len)
348 // debug: check descriptor for validity by verifying that desciptor link field is null as expected\n");
349          {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}
350 //just free pkt
351 Pktlib_freePacket((Ti_Pkt*)pkt);
352         return;
354 /* check header */
355 struct LastPktInfo
357 int iface;
358 int ipcsum;
359 int l4csum;
360 } ;
361 static struct LastPktInfo lpInfo;
363 int check_header(HEAD_T * p_head, PKTIO_METADATA_T * p_meta)
365 if (NWAL_RX_FLAG1_META_DATA_VALID & p_meta->u.rx_meta->rxFlag1)
367 lpInfo.iface = ((unsigned int)p_meta->u.rx_meta->appId) &0xff; //last byte is interface num
368 lpInfo.ipcsum =(p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_MASK )== NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_ACK ? 1 : 0;
369 lpInfo.l4csum = (p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_MASK )== ((NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_ACK) << NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_SHIFT) ? 1 : 0; 
371  return 1;
374 #define PKT_LEN 1400
375 void test_alloc_free(int n)
377 int i;
378 Ti_Pkt * b;
380 for(i=0;i<n;i++)
382   b=Pktlib_allocPacket(OurHeap,PKT_LEN);
383   Pktlib_freePacket(b);
386 /*-----------test driver: gen an input pkt------- */
387 //char buffer[sizeof(HEAD_T)+PKT_LEN];
388 Ti_Pkt * get_pkt(int n, unsigned int *p_len)
390    int ind;
391    long long temp;
392    Ti_Pkt * b;
393    char * buffer;
394    unsigned int len;
396   if (pktloopback==0)
397   {
398         if (n>=4) return NULL;   //just gen pkts to warm swtich, so that it knows
399                                 //our mac is valid
400   }  
401   b=Pktlib_allocPacket(OurHeap,PKT_LEN);
402   if (!b) 
403     {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};
405     //debug - way to validate descriptor
406     {Ti_Pkt* k= Pktlib_getNextPacket(b); 
407          if(k != 0) {printf(" genpkt, nexpkt != NULL");}}
410    //get pointer to buffer area of packet
411    Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len);
413 #if 0 
414 if (pktloopback==0)
416    temp = (long long) rand();
417    temp *= PKT_LEN;
418    temp /= RAND_MAX;
419    temp +=2;
420    *p_len = (int) temp; 
421    *p_len = *p_len &0xfffffffe;
422    temp = (long long) rand();
423    temp *= n_pkt;
424    temp /= RAND_MAX;
425    ind = (int) temp;
426    update_header(&pkts[ind],*p_len);
427    //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len);
428     memcpy(&buffer[0], &mac_header[0],14);
429     memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T)); 
431 else
432 #endif
434    //copy test packet into buffer
436     memcpy(&buffer[0], &testPkt[0],TEST_PKT_LEN);
437     *p_len = TEST_PKT_LEN;
439     return b; 
443 /******************************************************/
444 /******************PKT RECEIVE HANDLER *************************/
445 /******************************************************/
446 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
447                          PKTIO_METADATA_T meta[], int n_pkts,
448                          uint64_t ts )
450 int i;
451 int len;
452 int p;
453 HEAD_T * p_res;
454 Ti_Pkt * tip;
455 unsigned int templen;
456 int err;
457 KEY_T key;
458 char * p_pkt;
459 HEAD_T * p_head;
460 HEAD_T temp_head;
462     p_head=&temp_head;
464     //debug
465 #if 0
466     if (n_pkts != TX_BURST) {
467       printf("recv_cb, txsofar=%d rxsofar=%d  np = %d, NOT %d\n", 
468              stats.itx, stats.rx, n_pkts,TX_BURST);
469       our_stats_cb(netapi_handle,NULL);
470     }
471 #endif
472     //test_alloc_free(7);
473     //printf("recv start\n");
475    /* loop over received pkts */
476    for(i=0;i<n_pkts;i++)
477    {
478         tip = p_recv[i];
479         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
480         len = Pktlib_getPacketLen(tip);//real length
482          //debug: validate descriptor */
483          if(Pktlib_getNextPacket(tip) != 0) {printf(" rcv_cb, nexpkt != NULL");}
484         //debug printf("recv pkt, len=%d %d\n", len, templen);
485         stats.rx+=1;
487 #ifdef DEBUG_DESC
488    if (stats.rx<16){printf(">rx dmp.."); dump_descr((long *) tip, stats.rx);}
489    else if (stats.rx>99) {printf(">rx dmp.."); dump_descr((long *) tip,stats.rx);}
490 #endif
493         /* check header */
494         memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
495         if (!check_header(p_head,&meta[i])) { 
496                 stats.n_bad+=1;Pktlib_freePacket(tip); continue;
497         }
499         /* lookup flow */
500         key.src_ip = p_head->ip[3];
501         key.dst_ip = p_head->ip[4];
502         key.src_port= (p_head->udp[0]&0xffff0000)>>16;
503         key.dst_port= (p_head->udp[0]&0x0000ffff);
504         p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key));
505         if (!p_res) { stats.n_new+=1;  slow_path(tip, len); continue;}
507         /* copy header */
508         memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T));
510         memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));
511         /* update_mac(&p_pkt[0]);  */
513         /* 'simulate' send pkt */
514         send_pkt(tip,len);
515         stats.tx+=1;
516     }
517     //printf("recv done\n");
520 //timer callback 
521 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
522         int n_fired,     //# timers fired
523         NETAPI_TIMER_LIST_T fired_list,
524         uint64_t currentTime)
526 int i;
527 NETAPI_TIMER_T tx;
528 int cookie;
529 int err;
530 unsigned long long et;
531 printf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);
532 tx = netapi_TimerGetFirst(fired_list);
533 for(i=0;i<n_fired;i++)
535   cookie = (int) netapi_TimerGetCookie(tx);
536   et =  netapi_TimerGetTs(tx); //debug
537   printf("   timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);
538   if (cookie ==1)
539      t1 = netapi_TimerGroupStartTimer(
540         th,
541         (void *) 1,
542         100LL,  //timer group tics
543         &err);
544   else if (cookie ==2)
545       t2 = netapi_TimerGroupStartTimer(
546         th,
547         (void *) 2,
548         200LL,  //timer group ticks
549         &err);
550   else
551   {
552     t3 = netapi_TimerGroupStartTimer(
553         th,
554         (void *) 3,
555         300LL,  //timer group ticks
556         &err);
557     //cancel 1 and restart 1
558    netapi_TimerGroupCancel(th,t1,&err);
559    t1 = netapi_TimerGroupStartTimer(
560         th,
561         (void *) 1,
562         100LL,  //timer group ticks
563         &err);
564  }
565   tx = netapi_TimerGetNext(fired_list,tx); 
570 static int np2process = NP;
571 /******************************************************
572  * stats callback
573  *******************************************************/
574 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)
576 uint32_t numFreeDataPackets;
577 uint32_t numZeroBufferPackets;
578 uint32_t numPacketsinGarbage;
580 printf("stats @ %lld\n", netapi_getTimestamp());
581 if(pPaStats)
583        printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);
584        printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);
585        //printf("C1 number llc/snap fail:        %d\n", pPaStats->classify1.nLlcSnapFail);
586        printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);
587        printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);
588        printf ("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);
589        printf("C1 number of command failures:  %d\n", pPaStats->classify1.nCommandFail);
590        printf("C1 number invalid reply dests:  %d\n", pPaStats->classify1.nInvalidComReplyDest);
591        printf ("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);
592        printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);
593        printf ("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);
594        printf ("C1 number of system fails:      %d\n",pPaStats->classify1.nSystemFail);
595        printf ("C2 number parse failed  :      %d\n",pPaStats->classify2.nParseFail);
596        printf ("C2 number Invld Header  :      %d\n",pPaStats->classify2.nInvldHdr);
597        printf ("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);
598        printf ("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);
599        printf ("C2 number cmd fail      :      %d\n",pPaStats->classify2.nCommandFail);
600        printf ("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);
601        printf ("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);
603 Pktlib_getHeapStats(OurHeap, &numFreeDataPackets,
604                              &numZeroBufferPackets, &numPacketsinGarbage);
605 printf("heap stats>  #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets,
606                                 numZeroBufferPackets, numPacketsinGarbage);
607 //debug = dump timer polling stats
608 dump_poll_stats();
613 //******************************************************
614 //use scheduling housekeeping callback to generate pkts
615 //******************************************************
616 void house(NETAPI_SCHED_HANDLE_T * s)
618 Ti_Pkt * tip;
619 unsigned int len;
620 nwalTxPktInfo_t meta_tx={0};
621 PKTIO_METADATA_T meta = {PKTIO_META_TX,0};
622 int err;
623 static int house_pkts_gened=0;
624 int p;
625 unsigned char * pIpHdr,* pData;
627 for(p=0;p<TX_BURST;p++) {  
628 //reguest stats 
629 if ((house_pkts_gened>0) && (! (house_pkts_gened%400)) )
631    printf("net_test> request stats at n=%d \n",house_pkts_gened);
632    netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err); 
633    if (err!=0) {printf("stats req failed\n");}
637   if (house_pkts_gened >= np2process+ 100)
638   {
639      //shutdown
640      netapi_schedShutdown(s,NULL,&err);
641      continue;
642   }
644   else if (house_pkts_gened >= np2process) { house_pkts_gened+=1;  continue;}
645   
647 /* manufacture a pkt to transmit */
648    tip = get_pkt(house_pkts_gened, &len);
649    if(!tip) { house_pkts_gened +=1; continue; }
651    /* set the pkt length */
652    Pktlib_setPacketLen(tip, len);
654    /* set up meta data */
655     meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM);
656     meta_tx.startOffset = 0;
657     meta_tx.pktLen = len;
658     meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES;
659     meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES;
660     meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN;
661     meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;
662     meta_tx.ploadLen = TEST_PAYLOAD_LEN;
664     Pktlib_getDataBuffer(tip,&pData,&len);
665     pIpHdr = pData + meta_tx.ipOffBytes;
666     meta_tx.pseudoHdrChecksum =
667         test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));
669    /* post it to netcp tx channel*/
670    meta.u.tx_meta=&meta_tx;
671 #ifdef DEBUG_DESC
672    if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened);
673    else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened);
674 #endif
675    pktio_send(netcp_tx_chan,tip,&meta,&err);
676    if (err == 0) stats.itx +=1;
678    house_pkts_gened +=1;
679  }
683 /***************************************
684  ********** test driver*****************
685  ***************************************/
686 int main(int argc, char **argv)
688 int err;
689 rlim_t oss,ss = 1024*1024;
690 struct rlimit rl;
692 err= getrlimit(RLIMIT_STACK,&rl);
693 if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");
694 #if 0
695 rl.rlim_cur = ss;
696 err=setrlimit(RLIMIT_STACK,&rl);
697 if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");
698 #endif
700 if (argc>=2)  np2process = atoi(argv[1]);
701 if (np2process<0) np2process = NP; /* default */
702 if (argc==3)  perslow = atoi(argv[2]);
703 if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default
704 if (argc>3) {printf("net_test  <no of pkts to process> <percent slow path>\n"); exit(1);}
707 //real mode, so update our test packet mac header and ip header
708 if (pktloopback==0)
710 memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address
711 memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses
714 /*******************************************/
715 /*************NETAPI STARTUP****************/
716 /*******************************************/
718 /* create netapi */
719 netapi_handle = netapi_init(NETAPI_SYS_MASTER);
721 /* open the main heap */
722 OurHeap = Pktlib_findHeapByName("netapi");
723 if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}
725 /* create a pktio channel */
726 our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb, &our_chan_cfg,&err);
727 if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}
729 /* open netcp default tx, rx queues */
730 netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
731 if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}
732 netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg,  &err);
733 if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
736 /* create scheduler instance */
737 our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
738 if (!our_sched) {printf("sched create failed\n"); exit(1);}
740 /* add mac intefaces */
741 netcp_cfgCreateMacInterface(
742                   netapi_handle,
743                   &mac0[0],
744                   0,0,
745                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
746                   (NETCP_CFG_VLAN_T ) NULL ,  //future
747                   1, 
748                   &err);
749 if (err) {printf("addmac0 failed %d\n",err); exit(1); } 
751 //attach an IP to this interface
752 netcp_addIp(
753                   netapi_handle,
754                   0,
755                   nwal_IPV4,
756                   &OurIp0,
757                   NULL,  //all IP
758                   (NETCP_CFG_ROUTE_HANDLE_T) NULL,
759                   &err
760                   );
761 if (err) {printf("addip0 failed %d\n",err); exit(1); } 
762 #if 1
763 //create a 2nd mac instance
764 netcp_cfgCreateMacInterface(
765                   netapi_handle,
766                   &mac1[0],
767                   1,1,
768                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
769                   (NETCP_CFG_VLAN_T ) NULL ,  //future
770                   1,
771                   &err);
772 if (err) {printf("addmac1 failed %d\n",err); exit(1); }
774 //attach an IP to this interface
775 netcp_addIp(
776                   netapi_handle,
777                   1,
778                   nwal_IPV4,
779                   &OurIp1,
780                   NULL,  //all IP
781                   (NETCP_CFG_ROUTE_HANDLE_T) NULL,
782                   &err
783                   );
784 if (err) {printf("addip1 failed %d\n",err); exit(1); }
786 #endif
788  ourTimerBlock = netapi_TimerGroupCreate(
789         netapi_handle,
790         "our1sttimer",
791         our_timer_cb,
792         0,    //1 if timers local to thread
793         0,    //1 if expect to cancel
794         netapi_getTicksPerSec()/1000,  /* 1 msc resolution for these timers */
795         netapi_getTicksPerSec()/5000, /* would like .5 msc tolerence */
796         10,  //small # of timers to test garbage collection
797         &err);
798 if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}
800 //start a couple of timers 
801 t1 = netapi_TimerGroupStartTimer(
802         ourTimerBlock,
803         (void *) 1,
804         100LL,  //timer group ticks
805         &err);
806 if (err) {printf("timerstart failed %d\n");}
807 t2 = netapi_TimerGroupStartTimer(
808         ourTimerBlock,
809         (void *) 2,
810         200LL,  //timer group ticks
811         &err);
812 if (err) {printf("timerstart failed %d\n");}
813 t3 = netapi_TimerGroupStartTimer(
814         ourTimerBlock,
815         (void *) 3,
816         300LL,  //timer group ticks
817         &err);
818 if (err) {printf("timerstart failed %d\n");}
821 /*********************************************/
822 /*****************end NETAPI STARTUP**********/
823 /*********************************************/
826 /********************************************
827 * Basic pkt loopback test
828 *********************************************/
831 /* create TRIE */
832 P_trie = trie_new();
833 if (!P_trie) {printf("trie alloc failed\n"); exit(1);}
835 nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T));
836 if (!nat) {printf("malloc of nat table failed\n"); exit(1);}
838 //gen_pkts(np2process<NP ? np2process:NP);
839 n_pkt= np2process;
841 /* build table */
842 build_table(P_trie);
845 /* processing loop: get pkt, check it, look up in table, copy new header,
846    send packet */
847 srand((unsigned) np2process);
850 /*********************************************/
851 /**************Entry point into scheduler ****/
852 /*********************************************/
853 netapi_schedWaitForEvents(our_sched, &err);
855 /* done */
856 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);
857 our_stats_cb(netapi_handle, NULL);
859 netapi_shutdown(netapi_handle);