added del_ip, del_mac functions
[keystone-rtos/netapi.git] / ti / runtime / netapi / test / net_test.c
index 11d9c5dd14772060bef1e31fc012b22c81894427..fd0f55df2c8728cfe34fce78385c179011a99ca0 100755 (executable)
-/******************************************
- * File: net_test.c
- * Purpose: test app for netapi
- **************************************************************
- * FILE:  net_test.c
- * 
- * DESCRIPTION:  netapi user space transport
- *               library  test application
- * 
- * REVISION HISTORY:  rev 0.0.1 
- *
- *  Copyright (c) Texas Instruments Incorporated 2010-2011
- * 
- *  Redistribution and use in source and binary forms, with or without 
- *  modification, are permitted provided that the following conditions 
- *  are met:
- *
- *    Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer.
- *
- *    Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the   
- *    distribution.
- *
- *    Neither the name of Texas Instruments Incorporated nor the names of
- *    its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- *****************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-
-#include "trie.h"
-#include "string.h"
-#include "netapi.h"
-#include "pktio.h"
-#include <sys/resource.h>
-
-/*************debug********************/
-void dump_descr(unsigned long *p, int n)
-{
-   printf("--------dump of descriptor %d %x\n", n, (int) p);
-   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]);
-   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]);
-   printf("-----------------------------\n");
-}
-/*****************************************/
-
-
-//************for multi pkt burst  xfer test in loopback mode
-#define TX_BURST 4
-int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;
-
-//this device: 10.0.0.100, mac 0x,01,02,03,04,05  and .. 0x6
-
-//test packet, setup for loopback (so dest is ourself)
-static uint8_t testPkt[] = {
-
-  /* MAC header */
-  0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
-  0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04,
-  0x08, 0x00,
-
-  /* IP header */
-  0x45, 0x00,
-  0x00, 0x6c,  /* Length (including this header) */
-  0x00, 0x00, 0x00, 0x00, 0x05, 0x11,
-  0x00, 0x00,  /* Header checksum */
-  0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x64,
-
-  /* UDP header */
-  0x12, 0x34, 0x05, 0x55,
-  0x00, 0x58,  /* Length, including this header */
-  0x00, 0x00,  /* Header checksum */
-
- /* Payload */
-  0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-  0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
-  0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
-  0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
-  0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
-  0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,
-  0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
-  0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
-  0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
-  0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81
-
-};
-
-#define TEST_PAYLOAD_LEN            80
-
-#define TEST_PKT_IP_OFFSET_BYTES        14
-#define TEST_PKT_UDP_OFFSET_BYTES       34
-#define TEST_PKT_PLOAD_OFFSET_BYTES     42
-#define TEST_PKT_UDP_HDR_LEN            8
-/* Offsets to length fields */
-#define TEST_PKT_OFFSET_IP_LEN      16
-#define TEST_PKT_OFFSET_UDP_LEN     38
-
-#define TEST_PKT_LEN                122
-
-/* The pseudo header checksum of the packet except for the 16 bit length */
-#define TEST_PKT_PSEUDO_HDR_CHKSUM_SANS_LEN  0x0FFC
-
-
-
-#if 1
-//#include "arpa/inet.h"
-long htonl(long x)
-{
-       long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 |  (x&0xff)<<24 ;
-       return temp;
-}
-
-/********************************************************************
- *  FUNCTION PURPOSE: Ones complement addition utility
- ********************************************************************
- ********************************************************************/
-uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2)
-{
-  uint32_t result;
-
-  result = (uint32_t)v1 + (uint32_t)v2;
-  result = (result >> 16) + (result & 0xffff);
-  result = (result >> 16) + (result & 0xffff);
-
-  return ((uint16_t)result);
-}
-
-/********************************************************************
- *  FUNCTION PURPOSE: Ones complement checksum utility
- ********************************************************************
- ********************************************************************/
- uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords)
-{
-  uint16_t chksum = 0;
-  uint16_t v;
-  uint32_t i;
-  uint32_t j;
-
-  for (i = j = 0; i < nwords; i++, j+=2)  {
-    v = (p[j] << 8) | p[j+1];
-    chksum = test_utilOnesComplementAdd (chksum, v);
-  }
-  return (chksum);
-} /* utilOnesCompChkSum */
-
-/**************************************************************************************
- * FUNCTION PURPOSE: Compute ipv4 psudo checksum
- **************************************************************************************
- * DESCRIPTION: Compute ipv4 psudo checksum
- **************************************************************************************/
-uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen)
-{
-  uint16_t psudo_chksum;
-
-  psudo_chksum = test_utilOnesCompChkSum (&data[12], 4);
-  psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]);
-  psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen);
-
-  return (psudo_chksum);
-
-} /* utilGetIpv4PsudoChkSum */
-
-
-
-#endif
-typedef struct stats_t
-{
-        long itx;  //initially generated
-       long rx;
-       long tx;
-       long n_bad;
-       long n_new;
-} STATS_T;
-
-typedef struct head_t
-{
-       long ip[5];
-       long udp[2];
-} HEAD_T;
-
-typedef struct key_t
-{
-  long src_ip;
-  long dst_ip;
-  short src_port;
-  short dst_port;
-} KEY_T;
-
-unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0
-unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1
-nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-nwalIpAddr_t OurIp1={ 10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-#if 1  //goes with real tx (to laptop) 
-unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,
-                      0x00,0x01,0x02,0x03,0x04,0x05,
-                      0x08,0x00};
-unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa};
-#endif
-
-#if 0  //goes with loopback
-unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05, 
-                      0x00,0x11,0x22,0x33,0x44,0x55,
-                      0x08,0x00};
-#endif
-#define NE 65536 
-HEAD_T *nat;
-
-#define NP 5000
-int n_pkt = NP;
-STATS_T stats;
-
-Trie * P_trie;
-HEAD_T pkts[NP];
-#define PERSLOW  10  //% of pkts that will not be fastpath'd 
-int perslow= PERSLOW;
-
-/*******************************************
- *************NETAPI OBJECTS***************
- *****************************************/
-Pktlib_HeapHandle OurHeap;
-PKTIO_HANDLE_T *our_chan;
-PKTIO_HANDLE_T *netcp_rx_chan;
-PKTIO_HANDLE_T *netcp_tx_chan;
-PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
-PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
-PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
-
-void house(NETAPI_SCHED_HANDLE_T *s);
-NETAPI_T netapi_handle;
-NETAPI_SCHED_HANDLE_T * our_sched;
-NETAPI_SCHED_CONFIG_T our_sched_cfg={
-  NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 50  //every 50 poll loops
-};
-void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
-NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock; 
-NETAPI_TIMER_T t1;
-NETAPI_TIMER_T t2;
-NETAPI_TIMER_T t3;
-
-void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
-        int n_fired,     //# timers fired
-        NETAPI_TIMER_LIST_T fired_list,
-        uint64_t currentTime);
-
-/*************************END NETAPI OBJECTS***********************/
-
-#define START_SRC_IP 0x0a00000a
-#define DST_IP       0xc0a80001
-#define NEW_START_SRC_IP 0x9eda000a
-#define DST_PORT 0x555 
-#define START_SRC_PORT 0x1234
-#define NEW_START_SRC_PORT 100
-void update_header(HEAD_T * p_head, int len)
-{
-   unsigned char *p = (unsigned char *) &p_head->udp[1];
-   len -= (20+14);
-   /* update ip checksum */
-   /* update udp checksum */
-   /* update length */
-   *p= (len&0xff00)>>8;
-   *(p+1) = len&0xff;
-}
-
-#if 0
-void gen_pkts(int np)
-{
-int i;
-int ip = START_SRC_IP &0xff;
-int port= START_SRC_PORT;
-//HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP},
-//             {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}};
-HEAD_T temp;
-memcpy(&temp,&testPkt[0],sizeof(HEAD_T));
-
-for(i=0;(i<np) && (i<NP);i++)
-  {
-       memcpy(&pkts[i],&temp,sizeof(temp));
-       update_header(&pkts[i],512);      /* update checksums etc */
-       /* change template for new pkt */
-       ip+=1;
-       if(ip>254) {(ip=START_SRC_IP&0xff); port+=1; }
-       temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip);
-       temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port);
-       temp.udp[1] = htonl(temp.udp[1]);
-     
-  }
-  n_pkt=np;
-}
-#endif
-
-void build_table(Trie * p_trie)
-{
-int i;
-int sport=NEW_START_SRC_PORT; 
-HEAD_T temp,temp2;
-KEY_T key;
-
-memcpy(&temp,&testPkt[14],sizeof(temp));
-
- //insert entry into trie
-key.src_ip = temp.ip[3];
-key.dst_ip = temp.ip[4];
-key.src_port= (temp.udp[0]&0xffff0000)>>16;
-key.dst_port= (temp.udp[0]&0x0000ffff);
-trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[0]); //asociate with nat entry 0
-
-//build nat table
-for(i=0;i<100;i++)
-{
-   memcpy(&temp2,&testPkt[14],sizeof(temp));
-   temp2.udp[0] = (temp2.udp[0] & 0xffff0000) |  sport;
-   memcpy(&nat[i], &temp2, sizeof(temp2));
-   sport+= 1;
-}
-}
-
-//===========stub transmitter==================
-void send_pkt(Ti_Pkt *pkt, int len)
-{
-//just free pkt.  Don't send
-Pktlib_freePacket((Ti_Pkt*)pkt);
-       return;
-}
-
-//==========stub slow path============
-void slow_path(Ti_Pkt *pkt, int len)
-{
-// debug: check descriptor for validity by verifying that desciptor link field is null as expected\n");
-         {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}
-//just free pkt
-Pktlib_freePacket((Ti_Pkt*)pkt);
-       return;
-}
-/* check header */
-struct LastPktInfo
-{
-int iface;
-int ipcsum;
-int l4csum;
-} ;
-static struct LastPktInfo lpInfo;
-
-int check_header(HEAD_T * p_head, PKTIO_METADATA_T * p_meta)
-{
-if (NWAL_RX_FLAG1_META_DATA_VALID & p_meta->u.rx_meta->rxFlag1)
-{
-lpInfo.iface = ((unsigned int)p_meta->u.rx_meta->appId) &0xff; //last byte is interface num
-lpInfo.ipcsum =(p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_MASK )== NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_ACK ? 1 : 0;
-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; 
-}
- return 1;
-}
-
-#define PKT_LEN 1400
-void test_alloc_free(int n)
-{
-int i;
-Ti_Pkt * b;
-
-for(i=0;i<n;i++)
-{
-  b=Pktlib_allocPacket(OurHeap,PKT_LEN);
-  Pktlib_freePacket(b);
-}
-}
-/*-----------test driver: gen an input pkt------- */
-//char buffer[sizeof(HEAD_T)+PKT_LEN];
-Ti_Pkt * get_pkt(int n, unsigned int *p_len)
-{
-   int ind;
-   long long temp;
-   Ti_Pkt * b;
-   char * buffer;
-   unsigned int len;
-
-  if (pktloopback==0)
-  {
-       if (n>=4) return NULL;   //just gen pkts to warm swtich, so that it knows
-                                //our mac is valid
-  }  
-  b=Pktlib_allocPacket(OurHeap,PKT_LEN);
-  if (!b) 
-    {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};
-
-    //debug - way to validate descriptor
-    {Ti_Pkt* k= Pktlib_getNextPacket(b); 
-         if(k != 0) {printf(" genpkt, nexpkt != NULL");}}
-
-
-   //get pointer to buffer area of packet
-   Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len);
-
-#if 0 
-if (pktloopback==0)
-{
-   temp = (long long) rand();
-   temp *= PKT_LEN;
-   temp /= RAND_MAX;
-   temp +=2;
-   *p_len = (int) temp; 
-   *p_len = *p_len &0xfffffffe;
-   temp = (long long) rand();
-   temp *= n_pkt;
-   temp /= RAND_MAX;
-   ind = (int) temp;
-   update_header(&pkts[ind],*p_len);
-   //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len);
-    memcpy(&buffer[0], &mac_header[0],14);
-    memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T)); 
-}
-else
-#endif
-
-   //copy test packet into buffer
-{
-    memcpy(&buffer[0], &testPkt[0],TEST_PKT_LEN);
-    *p_len = TEST_PKT_LEN;
-}
-    return b; 
-}
-
-
-/******************************************************/
-/******************PKT RECEIVE HANDLER *************************/
-/******************************************************/
-void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
-                         PKTIO_METADATA_T meta[], int n_pkts,
-                         uint64_t ts )
-{
-int i;
-int len;
-int p;
-HEAD_T * p_res;
-Ti_Pkt * tip;
-unsigned int templen;
-int err;
-KEY_T key;
-char * p_pkt;
-HEAD_T * p_head;
-HEAD_T temp_head;
-
-    p_head=&temp_head;
-
-    //debug
-#if 0
-    if (n_pkts != TX_BURST) {
-      printf("recv_cb, txsofar=%d rxsofar=%d  np = %d, NOT %d\n", 
-             stats.itx, stats.rx, n_pkts,TX_BURST);
-      our_stats_cb(netapi_handle,NULL);
-    }
-#endif
-    //test_alloc_free(7);
-    //printf("recv start\n");
-
-   /* loop over received pkts */
-   for(i=0;i<n_pkts;i++)
-   {
-       tip = p_recv[i];
-       Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
-       len = Pktlib_getPacketLen(tip);//real length
-
-         //debug: validate descriptor */
-         if(Pktlib_getNextPacket(tip) != 0) {printf(" rcv_cb, nexpkt != NULL");}
-        //debug printf("recv pkt, len=%d %d\n", len, templen);
-       stats.rx+=1;
-
-#ifdef DEBUG_DESC
-   if (stats.rx<16){printf(">rx dmp.."); dump_descr((long *) tip, stats.rx);}
-   else if (stats.rx>99) {printf(">rx dmp.."); dump_descr((long *) tip,stats.rx);}
-#endif
-
-
-       /* check header */
-       memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
-       if (!check_header(p_head,&meta[i])) { 
-               stats.n_bad+=1;Pktlib_freePacket(tip); continue;
-       }
-
-       /* lookup flow */
-       key.src_ip = p_head->ip[3];
-       key.dst_ip = p_head->ip[4];
-       key.src_port= (p_head->udp[0]&0xffff0000)>>16;
-       key.dst_port= (p_head->udp[0]&0x0000ffff);
-       p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key));
-       if (!p_res) { stats.n_new+=1;  slow_path(tip, len); continue;}
-
-       /* copy header */
-       memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T));
-
-       memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));
-        /* update_mac(&p_pkt[0]);  */
-
-       /* 'simulate' send pkt */
-       send_pkt(tip,len);
-       stats.tx+=1;
-    }
-    //printf("recv done\n");
-}
-
-//timer callback 
-void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
-        int n_fired,     //# timers fired
-        NETAPI_TIMER_LIST_T fired_list,
-        uint64_t currentTime)
-{
-int i;
-NETAPI_TIMER_T tx;
-int cookie;
-int err;
-unsigned long long et;
-printf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);
-tx = netapi_TimerGetFirst(fired_list);
-for(i=0;i<n_fired;i++)
-{
-  cookie = (int) netapi_TimerGetCookie(tx);
-  et =  netapi_TimerGetTs(tx); //debug
-  printf("   timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);
-  if (cookie ==1)
-     t1 = netapi_TimerGroupStartTimer(
-        th,
-        (void *) 1,
-        100LL,  //timer group tics
-        &err);
-  else if (cookie ==2)
-      t2 = netapi_TimerGroupStartTimer(
-        th,
-        (void *) 2,
-        200LL,  //timer group ticks
-        &err);
-  else
-  {
-    t3 = netapi_TimerGroupStartTimer(
-        th,
-        (void *) 3,
-        300LL,  //timer group ticks
-        &err);
-    //cancel 1 and restart 1
-   netapi_TimerGroupCancel(th,t1,&err);
-   t1 = netapi_TimerGroupStartTimer(
-        th,
-        (void *) 1,
-        100LL,  //timer group ticks
-        &err);
- }
-  tx = netapi_TimerGetNext(fired_list,tx); 
-}
-}
-
-
-static int np2process = NP;
-/******************************************************
- * stats callback
- *******************************************************/
-void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)
-{
-uint32_t numFreeDataPackets;
-uint32_t numZeroBufferPackets;
-uint32_t numPacketsinGarbage;
-
-printf("stats @ %lld\n", netapi_getTimestamp());
-if(pPaStats)
-{
-       printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);
-       printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);
-       //printf("C1 number llc/snap fail:        %d\n", pPaStats->classify1.nLlcSnapFail);
-       printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);
-       printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);
-       printf ("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);
-       printf("C1 number of command failures:  %d\n", pPaStats->classify1.nCommandFail);
-       printf("C1 number invalid reply dests:  %d\n", pPaStats->classify1.nInvalidComReplyDest);
-       printf ("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);
-       printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);
-       printf ("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);
-       printf ("C1 number of system fails:      %d\n",pPaStats->classify1.nSystemFail);
-       printf ("C2 number parse failed  :      %d\n",pPaStats->classify2.nParseFail);
-       printf ("C2 number Invld Header  :      %d\n",pPaStats->classify2.nInvldHdr);
-       printf ("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);
-       printf ("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);
-       printf ("C2 number cmd fail      :      %d\n",pPaStats->classify2.nCommandFail);
-       printf ("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);
-       printf ("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);
-}
-Pktlib_getHeapStats(OurHeap, &numFreeDataPackets,
-                             &numZeroBufferPackets, &numPacketsinGarbage);
-printf("heap stats>  #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets,
-                                numZeroBufferPackets, numPacketsinGarbage);
-//debug = dump timer polling stats
-dump_poll_stats();
-
-
-}
-
-//******************************************************
-//use scheduling housekeeping callback to generate pkts
-//******************************************************
-void house(NETAPI_SCHED_HANDLE_T * s)
-{
-Ti_Pkt * tip;
-unsigned int len;
-nwalTxPktInfo_t meta_tx={0};
-PKTIO_METADATA_T meta = {PKTIO_META_TX,0};
-int err;
-static int house_pkts_gened=0;
-int p;
-unsigned char * pIpHdr,* pData;
-
-for(p=0;p<TX_BURST;p++) {  
-//reguest stats 
-if ((house_pkts_gened>0) && (! (house_pkts_gened%400)) )
-{
-   printf("net_test> request stats at n=%d \n",house_pkts_gened);
-   netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err); 
-   if (err!=0) {printf("stats req failed\n");}
-}
-
-
-  if (house_pkts_gened >= np2process+ 100)
-  {
-     //shutdown
-     netapi_schedShutdown(s,NULL,&err);
-     continue;
-  }
-
-  else if (house_pkts_gened >= np2process) { house_pkts_gened+=1;  continue;}
-  
-
-/* manufacture a pkt to transmit */
-   tip = get_pkt(house_pkts_gened, &len);
-   if(!tip) { house_pkts_gened +=1; continue; }
-
-   /* set the pkt length */
-   Pktlib_setPacketLen(tip, len);
-
-   /* set up meta data */
-    meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM);
-    meta_tx.startOffset = 0;
-    meta_tx.pktLen = len;
-    meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES;
-    meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES;
-    meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN;
-    meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;
-    meta_tx.ploadLen = TEST_PAYLOAD_LEN;
-
-    Pktlib_getDataBuffer(tip,&pData,&len);
-    pIpHdr = pData + meta_tx.ipOffBytes;
-    meta_tx.pseudoHdrChecksum =
-        test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));
-
-   /* post it to netcp tx channel*/
-   meta.u.tx_meta=&meta_tx;
-#ifdef DEBUG_DESC
-   if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened);
-   else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened);
-#endif
-   pktio_send(netcp_tx_chan,tip,&meta,&err);
-   if (err == 0) stats.itx +=1;
-
-   house_pkts_gened +=1;
- }
-}
-
-
-/***************************************
- ********** test driver*****************
- ***************************************/
-int main(int argc, char **argv)
-{
-int err;
-rlim_t oss,ss = 1024*1024;
-struct rlimit rl;
-
-err= getrlimit(RLIMIT_STACK,&rl);
-if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");
-#if 0
-rl.rlim_cur = ss;
-err=setrlimit(RLIMIT_STACK,&rl);
-if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");
-#endif
-
-if (argc>=2)  np2process = atoi(argv[1]);
-if (np2process<0) np2process = NP; /* default */
-if (argc==3)  perslow = atoi(argv[2]);
-if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default
-if (argc>3) {printf("net_test  <no of pkts to process> <percent slow path>\n"); exit(1);}
-
-
-//real mode, so update our test packet mac header and ip header
-if (pktloopback==0)
-{
-memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address
-memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses
-}
-
-/*******************************************/
-/*************NETAPI STARTUP****************/
-/*******************************************/
-
-/* create netapi */
-netapi_handle = netapi_init(NETAPI_SYS_MASTER);
-
-/* open the main heap */
-OurHeap = Pktlib_findHeapByName("netapi");
-if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}
-
-/* create a pktio channel */
-our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb, &our_chan_cfg,&err);
-if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}
-
-/* open netcp default tx, rx queues */
-netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
-if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}
-netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg,  &err);
-if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
-
-
-/* create scheduler instance */
-our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
-if (!our_sched) {printf("sched create failed\n"); exit(1);}
-
-/* add mac intefaces */
-netcp_cfgCreateMacInterface(
-                  netapi_handle,
-                  &mac0[0],
-                  0,0,
-                  (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
-                  (NETCP_CFG_VLAN_T ) NULL ,  //future
-                  1, 
-                  &err);
-if (err) {printf("addmac0 failed %d\n",err); exit(1); } 
-
-//attach an IP to this interface
-netcp_addIp(
-                  netapi_handle,
-                  0,
-                  nwal_IPV4,
-                  &OurIp0,
-                  NULL,  //all IP
-                  (NETCP_CFG_ROUTE_HANDLE_T) NULL,
-                  &err
-                  );
-if (err) {printf("addip0 failed %d\n",err); exit(1); } 
-#if 1
-//create a 2nd mac instance
-netcp_cfgCreateMacInterface(
-                  netapi_handle,
-                  &mac1[0],
-                  1,1,
-                  (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
-                  (NETCP_CFG_VLAN_T ) NULL ,  //future
-                  1,
-                  &err);
-if (err) {printf("addmac1 failed %d\n",err); exit(1); }
-
-//attach an IP to this interface
-netcp_addIp(
-                  netapi_handle,
-                  1,
-                  nwal_IPV4,
-                  &OurIp1,
-                  NULL,  //all IP
-                  (NETCP_CFG_ROUTE_HANDLE_T) NULL,
-                  &err
-                  );
-if (err) {printf("addip1 failed %d\n",err); exit(1); }
-
-#endif
-
- ourTimerBlock = netapi_TimerGroupCreate(
-        netapi_handle,
-        "our1sttimer",
-        our_timer_cb,
-        0,    //1 if timers local to thread
-        0,    //1 if expect to cancel
-        netapi_getTicksPerSec()/1000,  /* 1 msc resolution for these timers */
-        netapi_getTicksPerSec()/5000, /* would like .5 msc tolerence */
-        10,  //small # of timers to test garbage collection
-        &err);
-if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}
-
-//start a couple of timers 
-t1 = netapi_TimerGroupStartTimer(
-        ourTimerBlock,
-        (void *) 1,
-        100LL,  //timer group ticks
-        &err);
-if (err) {printf("timerstart failed %d\n");}
-t2 = netapi_TimerGroupStartTimer(
-        ourTimerBlock,
-        (void *) 2,
-        200LL,  //timer group ticks
-        &err);
-if (err) {printf("timerstart failed %d\n");}
-t3 = netapi_TimerGroupStartTimer(
-        ourTimerBlock,
-        (void *) 3,
-        300LL,  //timer group ticks
-        &err);
-if (err) {printf("timerstart failed %d\n");}
-
-
-/*********************************************/
-/*****************end NETAPI STARTUP**********/
-/*********************************************/
-
-
-/********************************************
-* Basic pkt loopback test
-*********************************************/
-
-
-/* create TRIE */
-P_trie = trie_new();
-if (!P_trie) {printf("trie alloc failed\n"); exit(1);}
-
-nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T));
-if (!nat) {printf("malloc of nat table failed\n"); exit(1);}
-
-//gen_pkts(np2process<NP ? np2process:NP);
-n_pkt= np2process;
-
-/* build table */
-build_table(P_trie);
-
-
-/* processing loop: get pkt, check it, look up in table, copy new header,
-   send packet */
-srand((unsigned) np2process);
-
-
-/*********************************************/
-/**************Entry point into scheduler ****/
-/*********************************************/
-netapi_schedWaitForEvents(our_sched, &err);
-
-/* done */
-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);
-our_stats_cb(netapi_handle, NULL);
-
-netapi_shutdown(netapi_handle);
-
-}
+/******************************************\r
+ * File: net_test.c\r
+ * Purpose: test app for netapi\r
+ **************************************************************\r
+ * FILE:  net_test.c\r
+ * \r
+ * DESCRIPTION:  netapi user space transport\r
+ *               library  test application\r
+ * \r
+ * REVISION HISTORY:  rev 0.0.1 \r
+ *\r
+ *  Copyright (c) Texas Instruments Incorporated 2010-2011\r
+ * \r
+ *  Redistribution and use in source and binary forms, with or without \r
+ *  modification, are permitted provided that the following conditions \r
+ *  are met:\r
+ *\r
+ *    Redistributions of source code must retain the above copyright \r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the \r
+ *    documentation and/or other materials provided with the   \r
+ *    distribution.\r
+ *\r
+ *    Neither the name of Texas Instruments Incorporated nor the names of\r
+ *    its contributors may be used to endorse or promote products derived\r
+ *    from this software without specific prior written permission.\r
+ *\r
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+ *****************************************/\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+#include <string.h>\r
+\r
+\r
+#include "trie.h"\r
+#include "string.h"\r
+#include "netapi.h"\r
+#include "pktio.h"\r
+#include <sys/resource.h>\r
+\r
+/*************debug********************/\r
+void dump_descr(unsigned long *p, int n)\r
+{\r
+   printf("--------dump of descriptor %d %x\n", n, (int) p);\r
+   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]);\r
+   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]);\r
+   printf("-----------------------------\n");\r
+}\r
+/*****************************************/\r
+\r
+\r
+//************for multi pkt burst  xfer test in loopback mode\r
+#define TX_BURST 4\r
+int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;\r
+\r
+//this device: 10.0.0.100, mac 0x,01,02,03,04,05  and .. 0x6\r
+\r
+//test packet, setup for loopback (so dest is ourself)\r
+static uint8_t testPkt[] = {\r
+\r
+  /* MAC header */\r
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05,\r
+  0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04,\r
+  0x08, 0x00,\r
+\r
+  /* IP header */\r
+  0x45, 0x00,\r
+  0x00, 0x6c,  /* Length (including this header) */\r
+  0x00, 0x00, 0x00, 0x00, 0x05, 0x11,\r
+  0x00, 0x00,  /* Header checksum */\r
+  0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x64,\r
+\r
+  /* UDP header */\r
+  0x12, 0x34, 0x05, 0x55,\r
+  0x00, 0x58,  /* Length, including this header */\r
+  0x00, 0x00,  /* Header checksum */\r
+\r
+ /* Payload */\r
+  0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,\r
+  0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,\r
+  0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,\r
+  0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,\r
+  0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,\r
+  0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,\r
+  0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,\r
+  0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,\r
+  0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,\r
+  0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81\r
+\r
+};\r
+\r
+#define TEST_PAYLOAD_LEN            80\r
+\r
+#define TEST_PKT_IP_OFFSET_BYTES        14\r
+#define TEST_PKT_UDP_OFFSET_BYTES       34\r
+#define TEST_PKT_PLOAD_OFFSET_BYTES     42\r
+#define TEST_PKT_UDP_HDR_LEN            8\r
+/* Offsets to length fields */\r
+#define TEST_PKT_OFFSET_IP_LEN      16\r
+#define TEST_PKT_OFFSET_UDP_LEN     38\r
+\r
+#define TEST_PKT_LEN                122\r
+\r
+/* The pseudo header checksum of the packet except for the 16 bit length */\r
+#define TEST_PKT_PSEUDO_HDR_CHKSUM_SANS_LEN  0x0FFC\r
+\r
+\r
+\r
+#if 1\r
+//#include "arpa/inet.h"\r
+long htonl(long x)\r
+{\r
+       long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 |  (x&0xff)<<24 ;\r
+       return temp;\r
+}\r
+\r
+/********************************************************************\r
+ *  FUNCTION PURPOSE: Ones complement addition utility\r
+ ********************************************************************\r
+ ********************************************************************/\r
+uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2)\r
+{\r
+  uint32_t result;\r
+\r
+  result = (uint32_t)v1 + (uint32_t)v2;\r
+  result = (result >> 16) + (result & 0xffff);\r
+  result = (result >> 16) + (result & 0xffff);\r
+\r
+  return ((uint16_t)result);\r
+}\r
+\r
+/********************************************************************\r
+ *  FUNCTION PURPOSE: Ones complement checksum utility\r
+ ********************************************************************\r
+ ********************************************************************/\r
+ uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords)\r
+{\r
+  uint16_t chksum = 0;\r
+  uint16_t v;\r
+  uint32_t i;\r
+  uint32_t j;\r
+\r
+  for (i = j = 0; i < nwords; i++, j+=2)  {\r
+    v = (p[j] << 8) | p[j+1];\r
+    chksum = test_utilOnesComplementAdd (chksum, v);\r
+  }\r
+  return (chksum);\r
+} /* utilOnesCompChkSum */\r
+\r
+/**************************************************************************************\r
+ * FUNCTION PURPOSE: Compute ipv4 psudo checksum\r
+ **************************************************************************************\r
+ * DESCRIPTION: Compute ipv4 psudo checksum\r
+ **************************************************************************************/\r
+uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen)\r
+{\r
+  uint16_t psudo_chksum;\r
+\r
+  psudo_chksum = test_utilOnesCompChkSum (&data[12], 4);\r
+  psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]);\r
+  psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen);\r
+\r
+  return (psudo_chksum);\r
+\r
+} /* utilGetIpv4PsudoChkSum */\r
+\r
+\r
+\r
+#endif\r
+typedef struct stats_t\r
+{\r
+        long itx;  //initially generated\r
+       long rx;\r
+       long tx;\r
+       long n_bad;\r
+       long n_new;\r
+} STATS_T;\r
+\r
+typedef struct head_t\r
+{\r
+       long ip[5];\r
+       long udp[2];\r
+} HEAD_T;\r
+\r
+typedef struct key_t\r
+{\r
+  long src_ip;\r
+  long dst_ip;\r
+  short src_port;\r
+  short dst_port;\r
+} KEY_T;\r
+\r
+unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0\r
+unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1\r
+nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
+nwalIpAddr_t OurIp1={ 10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
+\r
+#if 1  //goes with real tx (to laptop) \r
+unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,\r
+                      0x00,0x01,0x02,0x03,0x04,0x05,\r
+                      0x08,0x00};\r
+unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa};\r
+#endif\r
+\r
+#if 0  //goes with loopback\r
+unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05, \r
+                      0x00,0x11,0x22,0x33,0x44,0x55,\r
+                      0x08,0x00};\r
+#endif\r
+#define NE 65536 \r
+HEAD_T *nat;\r
+\r
+#define NP 5000\r
+int n_pkt = NP;\r
+STATS_T stats;\r
+\r
+Trie * P_trie;\r
+HEAD_T pkts[NP];\r
+#define PERSLOW  10  //% of pkts that will not be fastpath'd \r
+int perslow= PERSLOW;\r
+\r
+/*******************************************\r
+ *************NETAPI OBJECTS***************\r
+ *****************************************/\r
+Pktlib_HeapHandle OurHeap;\r
+PKTIO_HANDLE_T *our_chan;\r
+PKTIO_HANDLE_T *netcp_rx_chan;\r
+PKTIO_HANDLE_T *netcp_tx_chan;\r
+PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8};\r
+PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};\r
+PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};\r
+\r
+void house(NETAPI_SCHED_HANDLE_T *s);\r
+NETAPI_T netapi_handle;\r
+NETAPI_SCHED_HANDLE_T * our_sched;\r
+NETAPI_SCHED_CONFIG_T our_sched_cfg={\r
+  NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 50  //every 50 poll loops\r
+};\r
+void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);\r
+NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock; \r
+NETAPI_TIMER_T t1;\r
+NETAPI_TIMER_T t2;\r
+NETAPI_TIMER_T t3;\r
+\r
+void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,\r
+        int n_fired,     //# timers fired\r
+        NETAPI_TIMER_LIST_T fired_list,\r
+        uint64_t currentTime);\r
+\r
+NETCP_CFG_IP_T ip_rule0;\r
+NETCP_CFG_IP_T ip_rule1;\r
+/*************************END NETAPI OBJECTS***********************/\r
+\r
+#define START_SRC_IP 0x0a00000a\r
+#define DST_IP       0xc0a80001\r
+#define NEW_START_SRC_IP 0x9eda000a\r
+#define DST_PORT 0x555 \r
+#define START_SRC_PORT 0x1234\r
+#define NEW_START_SRC_PORT 100\r
+void update_header(HEAD_T * p_head, int len)\r
+{\r
+   unsigned char *p = (unsigned char *) &p_head->udp[1];\r
+   len -= (20+14);\r
+   /* update ip checksum */\r
+   /* update udp checksum */\r
+   /* update length */\r
+   *p= (len&0xff00)>>8;\r
+   *(p+1) = len&0xff;\r
+}\r
+\r
+#if 0\r
+void gen_pkts(int np)\r
+{\r
+int i;\r
+int ip = START_SRC_IP &0xff;\r
+int port= START_SRC_PORT;\r
+//HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP},\r
+//             {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}};\r
+HEAD_T temp;\r
+memcpy(&temp,&testPkt[0],sizeof(HEAD_T));\r
+\r
+for(i=0;(i<np) && (i<NP);i++)\r
+  {\r
+       memcpy(&pkts[i],&temp,sizeof(temp));\r
+       update_header(&pkts[i],512);      /* update checksums etc */\r
+       /* change template for new pkt */\r
+       ip+=1;\r
+       if(ip>254) {(ip=START_SRC_IP&0xff); port+=1; }\r
+       temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip);\r
+       temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port);\r
+       temp.udp[1] = htonl(temp.udp[1]);\r
+     \r
+  }\r
+  n_pkt=np;\r
+}\r
+#endif\r
+\r
+void build_table(Trie * p_trie)\r
+{\r
+int i;\r
+int sport=NEW_START_SRC_PORT; \r
+HEAD_T temp,temp2;\r
+KEY_T key;\r
+\r
+memcpy(&temp,&testPkt[14],sizeof(temp));\r
+\r
+ //insert entry into trie\r
+key.src_ip = temp.ip[3];\r
+key.dst_ip = temp.ip[4];\r
+key.src_port= (temp.udp[0]&0xffff0000)>>16;\r
+key.dst_port= (temp.udp[0]&0x0000ffff);\r
+trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[0]); //asociate with nat entry 0\r
+\r
+//build nat table\r
+for(i=0;i<100;i++)\r
+{\r
+   memcpy(&temp2,&testPkt[14],sizeof(temp));\r
+   temp2.udp[0] = (temp2.udp[0] & 0xffff0000) |  sport;\r
+   memcpy(&nat[i], &temp2, sizeof(temp2));\r
+   sport+= 1;\r
+}\r
+}\r
+\r
+//===========stub transmitter==================\r
+void send_pkt(Ti_Pkt *pkt, int len)\r
+{\r
+//just free pkt.  Don't send\r
+Pktlib_freePacket((Ti_Pkt*)pkt);\r
+       return;\r
+}\r
+\r
+//==========stub slow path============\r
+void slow_path(Ti_Pkt *pkt, int len)\r
+{\r
+// debug: check descriptor for validity by verifying that desciptor link field is null as expected\n");\r
+         {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}\r
+//just free pkt\r
+Pktlib_freePacket((Ti_Pkt*)pkt);\r
+       return;\r
+}\r
+/* check header */\r
+struct LastPktInfo\r
+{\r
+int iface;\r
+int ipcsum;\r
+int l4csum;\r
+} ;\r
+static struct LastPktInfo lpInfo;\r
+\r
+int check_header(HEAD_T * p_head, PKTIO_METADATA_T * p_meta)\r
+{\r
+if (NWAL_RX_FLAG1_META_DATA_VALID & p_meta->u.rx_meta->rxFlag1)\r
+{\r
+lpInfo.iface = ((unsigned int)p_meta->u.rx_meta->appId) &0xff; //last byte is interface num\r
+lpInfo.ipcsum =(p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_MASK )== NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_ACK ? 1 : 0;\r
+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; \r
+}\r
+ return 1;\r
+}\r
+\r
+#define PKT_LEN 1400\r
+void test_alloc_free(int n)\r
+{\r
+int i;\r
+Ti_Pkt * b;\r
+\r
+for(i=0;i<n;i++)\r
+{\r
+  b=Pktlib_allocPacket(OurHeap,PKT_LEN);\r
+  Pktlib_freePacket(b);\r
+}\r
+}\r
+/*-----------test driver: gen an input pkt------- */\r
+//char buffer[sizeof(HEAD_T)+PKT_LEN];\r
+Ti_Pkt * get_pkt(int n, unsigned int *p_len)\r
+{\r
+   int ind;\r
+   long long temp;\r
+   Ti_Pkt * b;\r
+   char * buffer;\r
+   unsigned int len;\r
+\r
+  if (pktloopback==0)\r
+  {\r
+       if (n>=4) return NULL;   //just gen pkts to warm swtich, so that it knows\r
+                                //our mac is valid\r
+  }  \r
+  b=Pktlib_allocPacket(OurHeap,PKT_LEN);\r
+  if (!b) \r
+    {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};\r
+\r
+    //debug - way to validate descriptor\r
+    {Ti_Pkt* k= Pktlib_getNextPacket(b); \r
+         if(k != 0) {printf(" genpkt, nexpkt != NULL");}}\r
+\r
+\r
+   //get pointer to buffer area of packet\r
+   Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len);\r
+\r
+#if 0 \r
+if (pktloopback==0)\r
+{\r
+   temp = (long long) rand();\r
+   temp *= PKT_LEN;\r
+   temp /= RAND_MAX;\r
+   temp +=2;\r
+   *p_len = (int) temp; \r
+   *p_len = *p_len &0xfffffffe;\r
+   temp = (long long) rand();\r
+   temp *= n_pkt;\r
+   temp /= RAND_MAX;\r
+   ind = (int) temp;\r
+   update_header(&pkts[ind],*p_len);\r
+   //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len);\r
+    memcpy(&buffer[0], &mac_header[0],14);\r
+    memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T)); \r
+}\r
+else\r
+#endif\r
+\r
+   //copy test packet into buffer\r
+{\r
+    memcpy(&buffer[0], &testPkt[0],TEST_PKT_LEN);\r
+    *p_len = TEST_PKT_LEN;\r
+}\r
+    return b; \r
+}\r
+\r
+\r
+/******************************************************/\r
+/******************PKT RECEIVE HANDLER *************************/\r
+/******************************************************/\r
+void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],\r
+                         PKTIO_METADATA_T meta[], int n_pkts,\r
+                         uint64_t ts )\r
+{\r
+int i;\r
+int len;\r
+int p;\r
+HEAD_T * p_res;\r
+Ti_Pkt * tip;\r
+unsigned int templen;\r
+int err;\r
+KEY_T key;\r
+char * p_pkt;\r
+HEAD_T * p_head;\r
+HEAD_T temp_head;\r
+\r
+    p_head=&temp_head;\r
+\r
+    //debug\r
+#if 0\r
+    if (n_pkts != TX_BURST) {\r
+      printf("recv_cb, txsofar=%d rxsofar=%d  np = %d, NOT %d\n", \r
+             stats.itx, stats.rx, n_pkts,TX_BURST);\r
+      our_stats_cb(netapi_handle,NULL);\r
+    }\r
+#endif\r
+    //test_alloc_free(7);\r
+    //printf("recv start\n");\r
+\r
+   /* loop over received pkts */\r
+   for(i=0;i<n_pkts;i++)\r
+   {\r
+       tip = p_recv[i];\r
+       Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen\r
+       len = Pktlib_getPacketLen(tip);//real length\r
+\r
+         //debug: validate descriptor */\r
+         if(Pktlib_getNextPacket(tip) != 0) {printf(" rcv_cb, nexpkt != NULL");}\r
+        //debug printf("recv pkt, len=%d %d\n", len, templen);\r
+       stats.rx+=1;\r
+\r
+#ifdef DEBUG_DESC\r
+   if (stats.rx<16){printf(">rx dmp.."); dump_descr((long *) tip, stats.rx);}\r
+   else if (stats.rx>99) {printf(">rx dmp.."); dump_descr((long *) tip,stats.rx);}\r
+#endif\r
+\r
+\r
+       /* check header */\r
+       memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));\r
+       if (!check_header(p_head,&meta[i])) { \r
+               stats.n_bad+=1;Pktlib_freePacket(tip); continue;\r
+       }\r
+\r
+       /* lookup flow */\r
+       key.src_ip = p_head->ip[3];\r
+       key.dst_ip = p_head->ip[4];\r
+       key.src_port= (p_head->udp[0]&0xffff0000)>>16;\r
+       key.dst_port= (p_head->udp[0]&0x0000ffff);\r
+       p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key));\r
+       if (!p_res) { stats.n_new+=1;  slow_path(tip, len); continue;}\r
+\r
+       /* copy header */\r
+       memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T));\r
+\r
+       memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));\r
+        /* update_mac(&p_pkt[0]);  */\r
+\r
+       /* 'simulate' send pkt */\r
+       send_pkt(tip,len);\r
+       stats.tx+=1;\r
+    }\r
+    //printf("recv done\n");\r
+}\r
+\r
+//timer callback \r
+void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,\r
+        int n_fired,     //# timers fired\r
+        NETAPI_TIMER_LIST_T fired_list,\r
+        uint64_t currentTime)\r
+{\r
+int i;\r
+NETAPI_TIMER_T tx;\r
+int cookie;\r
+int err;\r
+unsigned long long et;\r
+printf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);\r
+tx = netapi_TimerGetFirst(fired_list);\r
+for(i=0;i<n_fired;i++)\r
+{\r
+  cookie = (int) netapi_TimerGetCookie(tx);\r
+  et =  netapi_TimerGetTs(tx); //debug\r
+  printf("   timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);\r
+  if (cookie ==1)\r
+     t1 = netapi_TimerGroupStartTimer(\r
+        th,\r
+        (void *) 1,\r
+        100LL,  //timer group tics\r
+        &err);\r
+  else if (cookie ==2)\r
+      t2 = netapi_TimerGroupStartTimer(\r
+        th,\r
+        (void *) 2,\r
+        200LL,  //timer group ticks\r
+        &err);\r
+  else\r
+  {\r
+    t3 = netapi_TimerGroupStartTimer(\r
+        th,\r
+        (void *) 3,\r
+        300LL,  //timer group ticks\r
+        &err);\r
+    //cancel 1 and restart 1\r
+   netapi_TimerGroupCancel(th,t1,&err);\r
+   t1 = netapi_TimerGroupStartTimer(\r
+        th,\r
+        (void *) 1,\r
+        100LL,  //timer group ticks\r
+        &err);\r
+ }\r
+  tx = netapi_TimerGetNext(fired_list,tx); \r
+}\r
+}\r
+\r
+\r
+static int np2process = NP;\r
+/******************************************************\r
+ * stats callback\r
+ *******************************************************/\r
+void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)\r
+{\r
+uint32_t numFreeDataPackets;\r
+uint32_t numZeroBufferPackets;\r
+uint32_t numPacketsinGarbage;\r
+\r
+printf("stats @ %lld\n", netapi_getTimestamp());\r
+if(pPaStats)\r
+{\r
+       printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);\r
+       printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);\r
+       //printf("C1 number llc/snap fail:        %d\n", pPaStats->classify1.nLlcSnapFail);\r
+       printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);\r
+       printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);\r
+       printf ("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);\r
+       printf("C1 number of command failures:  %d\n", pPaStats->classify1.nCommandFail);\r
+       printf("C1 number invalid reply dests:  %d\n", pPaStats->classify1.nInvalidComReplyDest);\r
+       printf ("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);\r
+       printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);\r
+       printf ("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);\r
+       printf ("C1 number of system fails:      %d\n",pPaStats->classify1.nSystemFail);\r
+       printf ("C2 number parse failed  :      %d\n",pPaStats->classify2.nParseFail);\r
+       printf ("C2 number Invld Header  :      %d\n",pPaStats->classify2.nInvldHdr);\r
+       printf ("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);\r
+       printf ("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);\r
+       printf ("C2 number cmd fail      :      %d\n",pPaStats->classify2.nCommandFail);\r
+       printf ("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);\r
+       printf ("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);\r
+}\r
+Pktlib_getHeapStats(OurHeap, &numFreeDataPackets,\r
+                             &numZeroBufferPackets, &numPacketsinGarbage);\r
+printf("heap stats>  #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets,\r
+                                numZeroBufferPackets, numPacketsinGarbage);\r
+//debug = dump timer polling stats\r
+dump_poll_stats();\r
+\r
+\r
+}\r
+\r
+//******************************************************\r
+//use scheduling housekeeping callback to generate pkts\r
+//******************************************************\r
+void house(NETAPI_SCHED_HANDLE_T * s)\r
+{\r
+Ti_Pkt * tip;\r
+unsigned int len;\r
+nwalTxPktInfo_t meta_tx={0};\r
+PKTIO_METADATA_T meta = {PKTIO_META_TX,0};\r
+int err;\r
+static int house_pkts_gened=0;\r
+int p;\r
+unsigned char * pIpHdr,* pData;\r
+\r
+for(p=0;p<TX_BURST;p++) {  \r
+//reguest stats \r
+if ((house_pkts_gened>0) && (! (house_pkts_gened%400)) )\r
+{\r
+   printf("net_test> request stats at n=%d \n",house_pkts_gened);\r
+   netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err); \r
+   if (err!=0) {printf("stats req failed\n");}\r
+}\r
+\r
+\r
+  if (house_pkts_gened >= np2process+ 100)\r
+  {\r
+     //shutdown\r
+     netapi_schedShutdown(s,NULL,&err);\r
+     continue;\r
+  }\r
+\r
+  else if (house_pkts_gened >= np2process) { house_pkts_gened+=1;  continue;}\r
+  \r
+\r
+/* manufacture a pkt to transmit */\r
+   tip = get_pkt(house_pkts_gened, &len);\r
+   if(!tip) { house_pkts_gened +=1; continue; }\r
+\r
+   /* set the pkt length */\r
+   Pktlib_setPacketLen(tip, len);\r
+\r
+   /* set up meta data */\r
+    meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM);\r
+    meta_tx.startOffset = 0;\r
+    meta_tx.pktLen = len;\r
+    meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES;\r
+    meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES;\r
+    meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN;\r
+    meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;\r
+    meta_tx.ploadLen = TEST_PAYLOAD_LEN;\r
+\r
+    Pktlib_getDataBuffer(tip,&pData,&len);\r
+    pIpHdr = pData + meta_tx.ipOffBytes;\r
+    meta_tx.pseudoHdrChecksum =\r
+        test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));\r
+\r
+   /* post it to netcp tx channel*/\r
+   meta.u.tx_meta=&meta_tx;\r
+#ifdef DEBUG_DESC\r
+   if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened);\r
+   else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened);\r
+#endif\r
+   pktio_send(netcp_tx_chan,tip,&meta,&err);\r
+   if (err == 0) stats.itx +=1;\r
+\r
+   house_pkts_gened +=1;\r
+ }\r
+}\r
+\r
+\r
+/***************************************\r
+ ********** test driver*****************\r
+ ***************************************/\r
+int main(int argc, char **argv)\r
+{\r
+int err;\r
+rlim_t oss,ss = 1024*1024;\r
+struct rlimit rl;\r
+\r
+err= getrlimit(RLIMIT_STACK,&rl);\r
+if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");\r
+#if 0\r
+rl.rlim_cur = ss;\r
+err=setrlimit(RLIMIT_STACK,&rl);\r
+if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");\r
+#endif\r
+\r
+if (argc>=2)  np2process = atoi(argv[1]);\r
+if (np2process<0) np2process = NP; /* default */\r
+if (argc==3)  perslow = atoi(argv[2]);\r
+if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default\r
+if (argc>3) {printf("net_test  <no of pkts to process> <percent slow path>\n"); exit(1);}\r
+\r
+\r
+//real mode, so update our test packet mac header and ip header\r
+if (pktloopback==0)\r
+{\r
+memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address\r
+memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses\r
+}\r
+\r
+/*******************************************/\r
+/*************NETAPI STARTUP****************/\r
+/*******************************************/\r
+\r
+/* create netapi */\r
+netapi_handle = netapi_init(NETAPI_SYS_MASTER);\r
+\r
+/* open the main heap */\r
+OurHeap = Pktlib_findHeapByName("netapi");\r
+if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}\r
+\r
+/* create a pktio channel */\r
+our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb, &our_chan_cfg,&err);\r
+if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}\r
+\r
+/* open netcp default tx, rx queues */\r
+netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);\r
+if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}\r
+netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg,  &err);\r
+if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}\r
+\r
+\r
+/* create scheduler instance */\r
+our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);\r
+if (!our_sched) {printf("sched create failed\n"); exit(1);}\r
+\r
+/* add mac intefaces */\r
+netcp_cfgCreateMacInterface(\r
+                  netapi_handle,\r
+                  &mac0[0],\r
+                  0,0,\r
+                  (NETCP_CFG_ROUTE_HANDLE_T)  NULL,\r
+                  (NETCP_CFG_VLAN_T ) NULL ,  //future\r
+                  1, \r
+                  &err);\r
+if (err) {printf("addmac0 failed %d\n",err); exit(1); } \r
+\r
+//attach an IP to this interface\r
+ip_rule0=netcp_addIp(\r
+                  netapi_handle,\r
+                  0,\r
+                  nwal_IPV4,\r
+                  &OurIp0,\r
+                  NULL,  //all IP\r
+                  (NETCP_CFG_ROUTE_HANDLE_T) NULL,\r
+                  &err\r
+                  );\r
+if (err) {printf("addip0 failed %d\n",err); exit(1); } \r
+#if 1\r
+//create a 2nd mac instance\r
+netcp_cfgCreateMacInterface(\r
+                  netapi_handle,\r
+                  &mac1[0],\r
+                  1,1,\r
+                  (NETCP_CFG_ROUTE_HANDLE_T)  NULL,\r
+                  (NETCP_CFG_VLAN_T ) NULL ,  //future\r
+                  1,\r
+                  &err);\r
+if (err) {printf("addmac1 failed %d\n",err); exit(1); }\r
+\r
+//attach an IP to this interface\r
+ip_rule1=netcp_addIp(\r
+                  netapi_handle,\r
+                  1,\r
+                  nwal_IPV4,\r
+                  &OurIp1,\r
+                  NULL,  //all IP\r
+                  (NETCP_CFG_ROUTE_HANDLE_T) NULL,\r
+                  &err\r
+                  );\r
+if (err) {printf("addip1 failed %d\n",err); exit(1); }\r
+\r
+#endif\r
+\r
+ ourTimerBlock = netapi_TimerGroupCreate(\r
+        netapi_handle,\r
+        "our1sttimer",\r
+        our_timer_cb,\r
+        0,    //1 if timers local to thread\r
+        0,    //1 if expect to cancel\r
+        netapi_getTicksPerSec()/1000,  /* 1 msc resolution for these timers */\r
+        netapi_getTicksPerSec()/5000, /* would like .5 msc tolerence */\r
+        10,  //small # of timers to test garbage collection\r
+        &err);\r
+if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}\r
+\r
+//start a couple of timers \r
+t1 = netapi_TimerGroupStartTimer(\r
+        ourTimerBlock,\r
+        (void *) 1,\r
+        100LL,  //timer group ticks\r
+        &err);\r
+if (err) {printf("timerstart failed %d\n");}\r
+t2 = netapi_TimerGroupStartTimer(\r
+        ourTimerBlock,\r
+        (void *) 2,\r
+        200LL,  //timer group ticks\r
+        &err);\r
+if (err) {printf("timerstart failed %d\n");}\r
+t3 = netapi_TimerGroupStartTimer(\r
+        ourTimerBlock,\r
+        (void *) 3,\r
+        300LL,  //timer group ticks\r
+        &err);\r
+if (err) {printf("timerstart failed %d\n");}\r
+\r
+\r
+/*********************************************/\r
+/*****************end NETAPI STARTUP**********/\r
+/*********************************************/\r
+\r
+\r
+/********************************************\r
+* Basic pkt loopback test\r
+*********************************************/\r
+\r
+\r
+/* create TRIE */\r
+P_trie = trie_new();\r
+if (!P_trie) {printf("trie alloc failed\n"); exit(1);}\r
+\r
+nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T));\r
+if (!nat) {printf("malloc of nat table failed\n"); exit(1);}\r
+\r
+//gen_pkts(np2process<NP ? np2process:NP);\r
+n_pkt= np2process;\r
+\r
+/* build table */\r
+build_table(P_trie);\r
+\r
+\r
+/* processing loop: get pkt, check it, look up in table, copy new header,\r
+   send packet */\r
+srand((unsigned) np2process);\r
+\r
+\r
+/*********************************************/\r
+/**************Entry point into scheduler ****/\r
+/*********************************************/\r
+netapi_schedWaitForEvents(our_sched, &err);\r
+\r
+/* done */\r
+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);\r
+our_stats_cb(netapi_handle, NULL);\r
+\r
+netcp_cfgDelIp(netapi_handle, 0, 0, NULL, NULL, ip_rule0, &err);\r
+netcp_cfgDelIp(netapi_handle, 1, 0, NULL, NULL, ip_rule1, &err);\r
+netcp_cfgDelMac(netapi_handle,0,&err);\r
+netcp_cfgDelMac(netapi_handle,1,&err);\r
+\r
+netapi_shutdown(netapi_handle);\r
+\r
+}\r