]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/netapi.git/blobdiff - ti/runtime/netapi/test/net_test.c
Additional changes to integrate with highperf-lib, moved osal.c to highperf-lib
[keystone-rtos/netapi.git] / ti / runtime / netapi / test / net_test.c
old mode 100644 (file)
new mode 100755 (executable)
index 3877e14..4e88a29
-/******************************************\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
-//IPSEC MODE(only choose one rx and one tx)\r
-#define IPSEC_MODE_RX_INFLOW\r
-#define IPSEC_MODE_TX_INFLOW\r
-//#define IPSEC_MODE_RX_SIDEBAND\r
-//#define IPSEC_MODE_TX_SIDEBAND\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
-void dump_header(unsigned long *p, int n, int a, int r)\r
-{\r
-   printf("--------dump of header %d %x appID=%x flag1=%x\n", n, (int) p,a,r);\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("> %x %x %x %x %x %x %x %x\n",p[16],p[17],p[18],p[19],p[20],p[21],p[22],p[23]);\r
-   printf("> %x %x %x %x %x %x %x %x\n",p[24],p[25],p[26],p[27],p[28],p[29],p[30],p[31]);\r
-   printf("-----------------------------\n");\r
-}\r
-\r
-/*****************************************/\r
-\r
-\r
-//************for multi pkt burst  xfer test in loopback mode\r
-#define TX_BURST 800 \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
-        long n_class0_rx;   //count of pkts classified \r
-        long n_class1_rx;   //count of pkts classified \r
-        long n_class2_rx;   //count of pkts classified \r
-        long n_t1;\r
-        long n_t2;\r
-        long n_t3;\r
-        long sec_tx;\r
-        long sec_rx;\r
-        long sb_tx;\r
-        long sb_rx;\r
-        long secp_rx;\r
-        long n_auth_ok;\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
-nwalIpAddr_t OurIp2={ 10, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
-nwalIpAddr_t OurIp4IPSEC={ 192,168 , 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
-nwalIpAddr_t TheirIp4IPSEC={ 192,168 , 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
-\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
-Pktlib_HeapHandle specialSmall;\r
-Pktlib_HeapHandle specialLarge;\r
-\r
-PKTIO_HANDLE_T *our_chan;\r
-PKTIO_HANDLE_T *netcp_rx_chan;\r
-PKTIO_HANDLE_T *netcp_rx_chan2;\r
-PKTIO_HANDLE_T *netcp_tx_chan;\r
-PKTIO_HANDLE_T *netcp_sb_tx_chan;\r
-PKTIO_HANDLE_T *netcp_sb_rx_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_rx_cfg2={PKTIO_R, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8};\r
-PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};\r
-PKTIO_CFG_T netcp_sb_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};\r
-PKTIO_CFG_T netcp_sb_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, 500  //every 500 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
-NETCP_CFG_CLASS_T class_0;\r
-NETCP_CFG_CLASS_T class_1;\r
-NETCP_CFG_CLASS_T class_2;\r
-NETCP_CFG_FLOW_HANDLE_T specialFlow;\r
-\r
-NETCP_CFG_CLASSIFIER_T class_0_cfg=\r
-{\r
-   NETCP_CFG_CLASS_TYPE_L4,\r
-   {\r
-       {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2500}}\r
-   }\r
-};\r
-\r
-NETCP_CFG_CLASSIFIER_T class_1_cfg=\r
-{\r
-   NETCP_CFG_CLASS_TYPE_L4,\r
-   {\r
-        {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2502}}\r
-   }\r
-};\r
-\r
-NETCP_CFG_ROUTE_T  class2_route=\r
-{\r
-NULL, NULL  //* to be filled in\r
-};\r
-NETCP_CFG_CLASSIFIER_T class_2_cfg=  \r
-{\r
-   NETCP_CFG_CLASS_TYPE_L3_L4,\r
-   {\r
-        {0,  4 ,0/*fill in below*/ , NULL, NULL,          //L2/L3\r
-           NWAL_APP_PLOAD_PROTO_UDP, {2504}}   //L4\r
-   }\r
-};\r
-\r
-PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};\r
-\r
-/* security objects. (for loopback mode) */\r
-NETCP_CFG_SA_T rx_tunnel;\r
-NETCP_CFG_SA_T tx_tunnel;\r
-NETCP_CFG_IPSEC_POLICY_T rx_policy;\r
-void * rx_data_mode_handle;\r
-void * tx_data_mode_handle;\r
-void * rx_inflow_mode_handle;\r
-void * tx_inflow_mode_handle;\r
-/* rx */\r
-NETAPI_SEC_SA_INFO_T rx_sa=\r
-{\r
-        NWAL_SA_DIR_INBOUND,\r
-        0x44444444,  //spi\r
-        nwal_IpSecProtoESP, //ESP mode\r
-        nwal_SA_MODE_TUNNEL,  //tunnel mode\r
-        nwal_IPV4, //v4\r
-        { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */\r
-        { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/\r
-        64,/* replayWindow */\r
-        NWAL_SA_AALG_HMAC_SHA1,\r
-        NWAL_SA_EALG_AES_CBC,\r
-        0,0  //na\r
-};\r
-\r
-/*tx */\r
-NETAPI_SEC_SA_INFO_T tx_sa=\r
-{\r
-       NWAL_SA_DIR_OUTBOUND,\r
-       0x44444444,  //spi\r
-        nwal_IpSecProtoESP, //ESP mode\r
-        nwal_SA_MODE_TUNNEL,  //tunnel mode\r
-        nwal_IPV4, //v4\r
-        { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (us) -> set below */\r
-        { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (them) -> set below*/\r
-        64, /* NA replayWindow */\r
-        NWAL_SA_AALG_HMAC_SHA1,\r
-        NWAL_SA_EALG_AES_CBC,\r
-        0,0  //seq no\r
-};\r
-\r
-//since we are doing loopback, the rx key params = tx key params\r
-static nwalSecKeyParams_t ourTXKeyParams =\r
-{\r
-    16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_DES_CBC and 0 bytes Salt*/\r
-    20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_MD5 */\r
-    NULL, //set below\r
-    NULL, //set below\r
-};\r
-\r
-static nwalSecKeyParams_t ourRXKeyParams ={\r
-    16, /* encKeySize: 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_DES_CBC and 0 bytes Salt*/\r
-    20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_MD5 */\r
-    NULL, //set below\r
-    NULL, //set below\r
-};\r
-\r
-//keys\r
-static uint8_t ourAuthKey[36] =\r
-        {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,\r
-         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,\r
-         0x20, 0x21, 0x22, 0x23 };\r
-static uint8_t ourEncrKey[36] =\r
-        {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,\r
-         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,\r
-         0x30, 0x31, 0x32, 0x33 };\r
-\r
-\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
-if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC)\r
-{\r
-   stats.sec_rx++;\r
-}\r
-if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC_POLICY)\r
-{\r
-   stats.secp_rx++;\r
-}\r
-\r
-if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_CLASS)\r
-{\r
-  int c= ((unsigned int)p_meta->u.rx_meta->appId >>8)&0xffff;\r
-  if (c==0)  stats.n_class0_rx +=1;\r
-  else if (c==1) stats.n_class1_rx +=1;\r
-  else if (c==2) stats.n_class2_rx +=1;\r
-  else printf("**NET_TEST RX -unknown class: %x\n",  p_meta->u.rx_meta->appId);\r
-}\r
-}\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
-\r
-//measurement test points\r
-unsigned int vv1;\r
-unsigned int vv2;\r
-unsigned int vv3;\r
-unsigned int vv4;\r
-unsigned int vv5;\r
-unsigned int vv6;\r
-//these are updated by pktio.\r
-unsigned int vv7p;\r
-unsigned int vv8p;\r
-unsigned int vv9p;\r
-unsigned int vv10p;\r
-unsigned int vv11p;\r
-unsigned int vv12p;\r
-\r
-unsigned int vv11;\r
-\r
-/*--------------basic pktio send/recv benchmark----------------------*/\r
-unsigned int timings[10];\r
-void our_pktio_bench(int ntrials)\r
-{\r
-int i;\r
-#define NBATCH 8\r
-Ti_Pkt tip;\r
-unsigned char * pData;\r
-int len;\r
-int n;\r
-int err;\r
-int sum =0;\r
-\r
-   Osal_cache_op_measure_reset();\r
-   for(i=0;i<10;i++) timings[i]=0;\r
-   printf("calibration loop .. ");\r
-   for(i=0;i<1000;i++)\r
-   {\r
-   vv1= netapi_timing_stop();\r
-   vv2= netapi_timing_stop();\r
-   sum+=(vv2-vv1);\r
-   }\r
-   printf(" accuracy = +- %d cycles\n", sum/1000);\r
-   sleep(1);\r
-  \r
-PKTIO_METADATA_T meta[10]={0};\r
-//send single, recv single\r
-for(i=0;i<ntrials;i++)\r
-{\r
-   vv1= netapi_timing_stop();\r
-   tip=Pktlib_allocPacket(OurHeap,PKT_LEN);\r
-   vv2= netapi_timing_stop();\r
-   Pktlib_getDataBuffer(tip,&pData,&len);\r
-   vv3= netapi_timing_stop();\r
-   pktio_send(our_chan,tip,&meta[0],&err);\r
-   vv4= netapi_timing_stop();\r
-   n=pktio_poll(our_chan,NULL , &err);\r
-   vv5=   netapi_timing_stop();\r
-   timings[0]+=(vv6-vv4);\r
-   timings[1]+=(vv5-vv4);\r
-   timings[2]+=(vv7p-vv4);\r
-   timings[3]+=(vv4-vv3);\r
-   timings[4]+=(vv8p-vv3); \r
-   timings[5]+=(vv3-vv1);\r
-   timings[6]+=(vv9p-vv8p);\r
-   timings[7]+=(vv10p-vv7p);\r
-   timings[8]+=(vv11-vv6);\r
-}\r
-   printf("pktio bench. rx=%d (wcb%d) (toqm%d) tx=%d (toqm%d) alloc=%d qpush=%d qpop=%d free=%d\n", timings[0]/ntrials,\r
-           timings[1]/ntrials, timings[2]/ntrials,timings[3]/ntrials, timings[4]/ntrials,timings[5]/ntrials,\r
-           timings[6]/ntrials,timings[7]/ntrials, timings[8]/ntrials );\r
-   printf("raw qpop = %d  raw qpush = %d pa2va = %d  ", pktio_get_qop_time(), \r
-                                                        pktio_get_qpush_time(),\r
-                                                        pktio_get_pa2va_time());\r
-{\r
-   unsigned int ccycles;\r
-   int n_c_ops;\r
-   ccycles =Osal_cache_op_measure(&n_c_ops);\r
-   printf("n_c_ops=%d cache_op_time=%d (total) = %d (pp)\n", n_c_ops, ccycles,  n_c_ops? (ccycles/(n_c_ops)) : 0);\r
-}\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>=TX_BURST) 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
- *----------utility to flip a packet and send \r
- *--------------------back to source----------------------------\r
- *                   flag=1 => ipsec\r
- *--------------------------------------------------------------*/\r
-void flip_and_send_pkt(Ti_Pkt *tip,  unsigned char * p_pkt, int len, int flag)\r
-{\r
-unsigned char mac_temp[6];\r
-unsigned char ip_temp[4];\r
-unsigned char new_dest_port[2]={0x75,0x30};  // 30000\r
-uint16_t blah; \r
-//mac\r
-memcpy(&mac_temp,&p_pkt[0],6);\r
-memcpy(&p_pkt[0],&p_pkt[6],6);\r
-memcpy(&p_pkt[6],&mac_temp,6);\r
-//memcpy(&p_pkt[0],real_mac_header,6); //for testing to wireshark pc\r
-\r
-//ip  (outer in case of ipsec)\r
-memcpy(&ip_temp, &p_pkt[14+12],4);\r
-memcpy(&p_pkt[14+12],&p_pkt[14+12+4],4);\r
-memcpy(&p_pkt[14+12+4],&ip_temp,4);\r
-\r
-//outer checksum to 0\r
-if (!flag) memset(&p_pkt[14+10],0,2);\r
-\r
-//inner ip &udp for ipsec\r
-if (flag) \r
-{\r
-    //just drop non-udp packet\r
-    if (p_pkt[14+20+8+16+9]!=0x11)\r
-    {\r
-        stats.n_new+=1;Pktlib_freePacket(tip); return;\r
-    }\r
-\r
-//spi\r
-//memset(&p_pkt[14+20],0x88,4); \r
-//inner ip\r
-memcpy(&ip_temp, &p_pkt[14+20+8+16+12],4);\r
-memcpy(&p_pkt[14+20+8+16+12],&p_pkt[14+20+8+16+12+4],4);\r
-memcpy(&p_pkt[14+20+8+16+12+4],&ip_temp,4);\r
-\r
-//udp\r
-memcpy(&p_pkt[14+20+8+16+20+2],&new_dest_port[0],2);\r
-memset(&p_pkt[14+20+8+16+20+6],0,2); //checksum\r
-\r
-#ifdef IPSEC_MODE_TX_SIDEBAND\r
-\r
-//inner ip checksum : leave alone\r
-#if 0\r
-blah=test_utilOnesCompChkSum (&p_pkt[14+20+8+16], 10);\r
-p_pkt[14+20+8+16+10]= (blah&0xff00)>>8;\r
-p_pkt[14+20+8+16+11]= blah&0xff;\r
-#endif\r
-\r
-//tbd udp checksum (leave at 0)\r
-\r
-//outer ip, set to 0 (we will compute on way out\r
-memset(&p_pkt[14+10],0,2);\r
-\r
-#else //inflow, don't touch outer , clear inner \r
-memset(&p_pkt[14+20+8+16+10],0,2); //inner checksum, we will compute on way out\r
-//outer ip checksum : leave alone\r
-#if 0\r
-blah = test_utilOnesCompChkSum (&p_pkt[14], 10);\r
-p_pkt[14+10]= (blah&0xff00)>>8;\r
-p_pkt[14+11]= blah&0xff;\r
-#endif\r
-#endif\r
-}\r
-else\r
-{\r
-memset(&p_pkt[14+20+6],0,2);//0 udp checksum (we will compute on way out\r
-memcpy(&p_pkt[14+20+2],&new_dest_port[0],2);\r
-}\r
-\r
-//IPSEC case, \r
-if (flag)\r
-{\r
-#ifdef IPSEC_MODE_TX_SIDEBAND\r
- //send to crypto for encryption\r
-//12 byte auth tag\r
-        {\r
-           PKTIO_METADATA_T meta = {PKTIO_META_SB_TX,{0},0};\r
-           int err;\r
-           nwalDmTxPayloadInfo_t meta_tx={0};\r
-           meta.sa_handle=tx_data_mode_handle;  //use TX SA context\r
-           meta_tx.ploadLen = len;\r
-           meta_tx.encOffset = 14+20+8+16 ;\r
-           meta_tx.authOffset =14+20 ;\r
-           meta_tx.encSize=len - 14- 20-8-16-12;\r
-           meta_tx.authSize= len -14-20-12;\r
-           meta_tx.encIvSize=16;\r
-           meta_tx.pEncIV= &p_pkt[14+20+8];  //just use same IV..\r
-           meta_tx.authIvSize=0;\r
-           meta_tx.pAuthIV=NULL;\r
-           meta_tx.aadSize=0;\r
-           meta_tx.pAad=NULL;\r
-           /* post it to netcp sb tx channel*/\r
-           meta.u.tx_sb_meta=&meta_tx;\r
-           pktio_send(netcp_sb_tx_chan,tip,&meta,&err);\r
-       }\r
-\r
-#else\r
- {\r
-  //inflow tx\r
-  //send pkt directly, asking for IP and UDP checksum offloads AND IPSEC to be applied\r
-           PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};\r
-           int err;\r
-           nwalTxPktInfo_t meta_tx={0};\r
-           meta.sa_handle=tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied\r
-           meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_META_DATA_VALID );\r
-           meta_tx.saOffBytes=14+20;  \r
-           meta_tx.saPayloadLen=len-14-20;   //don't include tag, mac and outer header\r
-           meta_tx.startOffset = 0;\r
-           meta_tx.ipOffBytes = 14+20+8+16;   //to inner header\r
-           meta_tx.l4OffBytes = 14+20+8+16+20; //to L4 \r
-           meta_tx.l4HdrLen = 8;\r
-           meta_tx.ploadLen = (unsigned) ((p_pkt[14+20+8+16+20+4]<<8)|p_pkt[14+20+8+16+20+4+1]) -8 ;\r
-           meta_tx.pseudoHdrChecksum =\r
-             test_utilGetIpv4PsudoChkSum(&p_pkt[14+20+8+16],8+ meta_tx.ploadLen);\r
-\r
-           /* post it to netcp tx channel*/\r
-           meta.u.tx_meta=&meta_tx;\r
-           pktio_send(netcp_tx_chan,tip,&meta,&err);\r
-           stats.tx +=1;\r
-           stats.sec_tx +=1;\r
-     }\r
-#endif\r
-\r
-\r
-}\r
-else  //non ipsec send pkt directly, asking for IP and UDP checksum ofload\r
-{\r
-           PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};\r
-           int err;\r
-           nwalTxPktInfo_t meta_tx2={0};\r
-           meta2.sa_handle=nwal_HANDLE_INVALID;\r
-           meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );\r
-           meta_tx2.startOffset = 0;\r
-           meta_tx2.ipOffBytes = 14;\r
-           meta_tx2.l4OffBytes = 14+20;\r
-           meta_tx2.l4HdrLen = 8;\r
-           meta_tx2.ploadLen = (unsigned) ((p_pkt[14+20+4]<<8)|p_pkt[14+20+4+1]) -8 ;\r
-           meta_tx2.pseudoHdrChecksum =\r
-             test_utilGetIpv4PsudoChkSum(&p_pkt[14],8+ meta_tx2.ploadLen);\r
-\r
-           /* post it to netcp tx channel*/\r
-           meta2.u.tx_meta=&meta_tx2;\r
-           pktio_send(netcp_tx_chan,tip,&meta2,&err);\r
-           stats.tx +=1;\r
-}\r
-}\r
-\r
-\r
-\r
-\r
-/***************************************\r
- benchmark receive handler\r
-****************************************/\r
-void recv_cb_bench(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
-   vv6=   netapi_timing_stop();\r
-   for (i=0;i<n_pkts; i++) Pktlib_freePacket(p_recv[i]);\r
-   vv11 = netapi_timing_stop();\r
-}\r
-\r
-/****************************************************************************************/\r
-/******************SB Accelerator Callback PKT RECEIVE HANDLER *************************/\r
-/******************  Handles Decrypt and Encrypt operation callbacks ******************/\r
-/******************************************************************************************/\r
-void recv_sb_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
-int tag_cmp=0;\r
-unsigned int hash[3];\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
-        //is this a decrypt (rx_tunnel) complete\r
-        if (meta[i].u.rx_sb_meta->appId == rx_tunnel)\r
-        {\r
-           stats.sb_rx+=1;\r
-           //copy hash out of meta data (for some reason it needs endian conversion)\r
-           hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);\r
-           hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);\r
-           hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]);\r
-\r
-           if(stats.sb_rx<=16)\r
-           {\r
-             char *tp = (char *) &hash[0];\r
-             dump_header((long*)p_pkt, stats.sb_rx, meta[i].u.rx_sb_meta->appId,0);\r
-             printf("tag in pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n",\r
-                      p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],\r
-                      p_pkt[len-7],p_pkt[len-6],\r
-                      p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]);\r
-             printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n",\r
-                       tp[0],tp[1],tp[2],tp[3],tp[4],tp[5],\r
-                       tp[6],tp[7],tp[8],tp[9],tp[10],tp[11]);\r
-           }\r
-           //check tag \r
-           tag_cmp = memcmp(&p_pkt[len-12],(char*) &hash[0],12); //todo, really use meta->authTagLen\r
-           stats.n_auth_ok += !(tag_cmp);\r
-          flip_and_send_pkt(tip, p_pkt, len,1);  //flip packet to echo back and send\r
-        }\r
-        //this is an encrypt (tx tunnel) complete\r
-        else if(meta[i].u.rx_sb_meta->appId== tx_tunnel )\r
-        {\r
-           hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);\r
-           hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);\r
-           hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]);\r
-           stats.sb_tx+=1;\r
-           if(stats.sb_tx<=16)\r
-           {\r
-             char *tp1 = (char *) &hash[0];\r
-             dump_header((long*)p_pkt, stats.sb_tx, meta[i].u.rx_sb_meta->appId,0);\r
-             printf("tag in original rx pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n",\r
-                      p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],\r
-                      p_pkt[len-7],p_pkt[len-6],\r
-                      p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]);\r
-\r
-             printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n",\r
-                       tp1[0],tp1[1],tp1[2],tp1[3],tp1[4],tp1[5],\r
-                       tp1[6],tp1[7],tp1[8],tp1[9],tp1[10],tp1[11]);\r
-           }\r
-           //put the computed tag in the packet\r
-           memcpy(&p_pkt[len-12],(char*)&hash[0],12); //todo, really use meta->authTagLen\r
-           {\r
-          PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};\r
-           nwalTxPktInfo_t meta_tx={0};\r
-           // now send directly \r
-           meta2.sa_handle=nwal_HANDLE_INVALID;\r
-           meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID);//only outer IP header checksum. no udp checksum possible since pkt is already encrypted\r
-           meta_tx.startOffset = 0;\r
-           meta_tx.ipOffBytes = 14;\r
-           //not used\r
-           meta_tx.l4OffBytes = 0;\r
-           meta_tx.l4HdrLen = 0;\r
-           meta_tx.ploadLen = 0;\r
-\r
-           /* post it to netcp tx channel*/\r
-           meta2.u.tx_meta=&meta_tx;\r
-           pktio_send(netcp_tx_chan,tip,&meta2,&err);\r
-           stats.tx +=1;\r
-           }\r
-        }\r
-        else printf("netapi recv_sb_cb: unknown appiD %x \n",meta[i].u.rx_sb_meta->appId );\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)-4;//real length, subtract mac trailer\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
-    if(stats.rx<=16)\r
-    {\r
-       dump_header((long*)p_pkt, stats.rx, meta[i].u.rx_meta->appId,meta[i].u.rx_meta->rxFlag1);\r
-    }\r
-       /* check header */\r
-       memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));\r
-\r
-        if ((p_head->ip[2]&0x0000ff00)==0x00003200)\r
-        {\r
-             if (!check_header(p_head,&meta[i])) {\r
-                stats.n_bad+=1;Pktlib_freePacket(tip); continue;\r
-             }\r
\r
-             //process IP SEC PACKET\r
-#ifdef IPSEC_MODE_RX_SIDEBAND\r
-        {\r
-           //ship to crypto for decrypt!!\r
-           //12 byte auth tag\r
-          PKTIO_METADATA_T meta2 = {PKTIO_META_SB_TX,{0},0};\r
-           nwalDmTxPayloadInfo_t meta_tx={0};\r
-           meta2.sa_handle=rx_data_mode_handle;\r
-           meta_tx.ploadLen = len;\r
-           meta_tx.encOffset = 14+20+8+16 ;\r
-           meta_tx.authOffset =14+20 ;\r
-           meta_tx.encSize=len - 14- 20-8-16-12;\r
-           meta_tx.authSize= len -14-20-12;\r
-           meta_tx.encIvSize=16;\r
-           meta_tx.pEncIV= &p_pkt[14+20+8];\r
-           meta_tx.authIvSize=0;\r
-           meta_tx.pAuthIV=NULL;\r
-           meta_tx.aadSize=0;\r
-           meta_tx.pAad=NULL;\r
-           /* post it to netcp sb tx channel*/\r
-           meta2.u.tx_sb_meta=&meta_tx;\r
-           pktio_send(netcp_sb_tx_chan,tip,&meta2,&err);\r
-           continue;\r
-        }\r
-#else \r
-        //inflow mode.  flip and send\r
-        flip_and_send_pkt(tip,p_pkt,len,1);\r
-#endif\r
-    }\r
-    else if ((p_head->ip[2]&0x0000ff00)!=0x00001100)\r
-    {\r
-               stats.n_new+=1;Pktlib_freePacket(tip); continue;\r
-    }\r
-    else  //non ipsec\r
-    {\r
-       if (!check_header(p_head,&meta[i])) { \r
-               stats.n_bad+=1;Pktlib_freePacket(tip); continue;\r
-       }\r
-\r
-#if 0\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
-#endif\r
-        //just flip and send\r
-        flip_and_send_pkt(tip,p_pkt,len,0);\r
-    }\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
-//DEBUGprintf("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
-  //DEBUGprintf("   timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);\r
-  if (cookie ==1)\r
-  {  \r
-     stats.n_t1+=1;\r
-     t1 = netapi_TimerGroupStartTimer(\r
-        th,\r
-        (void *) 1,\r
-        100LL,  //timer group tics\r
-        &err);\r
-  }\r
-  else if (cookie ==2)\r
-  {\r
-      stats.n_t2+=1;\r
-      t2 = netapi_TimerGroupStartTimer(\r
-        th,\r
-        (void *) 2,\r
-        200LL,  //timer group ticks\r
-        &err);\r
-  }\r
-  else\r
-  {\r
-    stats.n_t3+=1;\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
-//printf("netcp_tx_handle check %x\n", netcp_tx_chan->back);\r
-printf(">itx=%d rx=%d tx=%d bad=%d slow=%d \n>rx_class0=%d rx_class1=%d rx_class2=%d  secRx=%d  secPRX=%d sb_rx=%d sb_tx=%d auth_ok=%d\n  n_t1=%d n_t2=%d n_t3=%d\n",stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new, \r
-         stats.n_class0_rx, stats.n_class1_rx, \r
-         stats.n_class2_rx, stats.sec_rx, stats.secp_rx, stats.sb_rx, stats.sb_tx, stats.n_auth_ok,\r
-         stats.n_t1, stats.n_t2,stats.n_t3);\r
-\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("main heap stats>  #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets,\r
-                                numZeroBufferPackets, numPacketsinGarbage);\r
-Pktlib_getHeapStats(specialSmall, &numFreeDataPackets,\r
-                             &numZeroBufferPackets, &numPacketsinGarbage);\r
-printf("specialSmall heap stats>  #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets,\r
-                                numZeroBufferPackets, numPacketsinGarbage);\r
-Pktlib_getHeapStats(specialLarge, &numFreeDataPackets,\r
-                             &numZeroBufferPackets, &numPacketsinGarbage);\r
-printf("specialLarge heap stats>  #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets,\r
-                                numZeroBufferPackets, numPacketsinGarbage);\r
-\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;\r
-PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};\r
-int err;\r
-static int house_pkts_gened=0;\r
-int p;\r
-unsigned char * pIpHdr,* pData;\r
-unsigned int vv1,vv2,vv3;\r
-unsigned int sum_vv1=0;\r
-unsigned int sum_vv2=0;\r
-unsigned int sum_vv3=0;\r
-unsigned int sum_vv4=0;\r
-unsigned int sum_vv5=0;\r
-\r
-Osal_cache_op_measure_reset();\r
-memset(&meta_tx,0,sizeof(meta_tx));\r
-for(p=0;p<TX_BURST;p++) {  \r
-//reguest stats \r
-if ((house_pkts_gened>0) && (! (house_pkts_gened%1000)) )\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
-\r
-   /* set the pkt length */\r
-   vv1 = netapi_timing_start();\r
-   Pktlib_setPacketLen(tip, len);\r
-\r
-   /* set up meta data */\r
-    meta.sa_handle=nwal_HANDLE_INVALID;\r
-    meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID);\r
-    meta_tx.startOffset = 0;\r
-    //GONE in V2 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
-    //GONE in V2 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
-   vv2= netapi_timing_stop();\r
-   pktio_send(netcp_tx_chan,tip,&meta,&err);\r
-   vv3= netapi_timing_stop();\r
-   sum_vv1 += (vv3-vv1);\r
-   sum_vv2 += (vv2-vv1);\r
-   sum_vv3 += (vv3-vv2);\r
-   sum_vv4 += (vv11p-vv2);\r
-   sum_vv5 += (vv12p-vv11p);\r
-   // printf("pktio send. full=%d metadata=%d pktio_send=%d\n", vv3-vv1,  vv2-vv1,  vv3-vv2);\r
-   if (err == 0) stats.itx +=1;\r
-\r
-   house_pkts_gened +=1;\r
- }\r
-{\r
-   unsigned int ccycles;\r
-   int n_c_ops;\r
-   ccycles =Osal_cache_op_measure(&n_c_ops);\r
-   if (sum_vv1) \r
-      printf("BURST pktio send %d pkts. full=%d metadata=%d pktio_send=%d to_nwal=%d nwal_send= %d n_c_ops=%d cache_op_time=%d (pp-> %d)\n", stats.itx,\r
-   sum_vv1/stats.itx,  sum_vv2/stats.itx,  sum_vv3/stats.itx, \r
-   sum_vv4/stats.itx,  sum_vv5/stats.itx, n_c_ops, ccycles,  \r
-   n_c_ops? (ccycles/(n_c_ops/2)) : 0);\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 two secondary heaps */\r
-specialSmall = Pktlib_createHeap("netapi-small", NETAPI_GLOBAL_REGION,\r
-                                                1,\r
-                                                256, //bytes\r
-                                                64,  //num buffs\r
-                                                0,\r
-                                                netapi_getPktlibIfTable());\r
-specialLarge = Pktlib_createHeap("netapi-small", NETAPI_GLOBAL_REGION,\r
-                                                1,\r
-                                                1600, //bytes\r
-                                                64,  //num buffs\r
-                                                0,\r
-                                                netapi_getPktlibIfTable());\r
-//register these heaps so poll routine will include their garbage queues.\r
-netapi_registerHeap(netapi_handle, specialSmall);\r
-netapi_registerHeap(netapi_handle, specialLarge);\r
-\r
-\r
-/* create a pktio channel */\r
-our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb_bench, &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
-/* create a pktio channel for specially classified pkts */\r
-netcp_rx_chan2= pktio_create(netapi_handle, "classq", (PKTIO_CB) recv_cb, &netcp_rx_cfg2,  &err);\r
-if (!netcp_rx_chan2) {printf("pktio create RX2 failed err=%d\n",err); exit(1);}\r
-\r
-/* open netcp default tx, rx queues for sideband crypto */\r
-netcp_sb_tx_chan= pktio_open(netapi_handle, NETCP_SB_TX, NULL, &netcp_sb_tx_cfg,  &err);\r
-if (!netcp_sb_tx_chan) {printf("pktio open SB TX failed err=%d\n",err); exit(1);}\r
-netcp_sb_rx_chan= pktio_open(netapi_handle, NETCP_SB_RX, (PKTIO_CB) recv_sb_cb, &netcp_sb_rx_cfg,  &err);\r
-if (!netcp_sb_rx_chan) {printf("pktio open SB 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
-/********************************************\r
-* Basic pkt loopback test\r
-*********************************************/\r
-printf("...runnining pure push/pop benchmark\n");\r
-our_pktio_bench(1000);\r
-our_pktio_bench(1000);\r
-our_pktio_bench(1000);\r
-our_pktio_bench(1000);\r
-our_pktio_bench(1000);\r
-/*********************************************/\r
-\r
-\r
-\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
-//attach 2 classifiers to iface 0, ip0\r
-class_0_cfg.u.c_l4.ip = ip_rule0;\r
-class_0 =  netcp_cfgAddClass(netapi_handle,\r
-                             &class_0_cfg,\r
-                             NULL,\r
-                             NETCP_CFG_ACTION_TO_SW,\r
-                            &err);\r
-if (err) {printf("addclass0 failed %d\n",err); exit(1);}\r
-\r
-class_1_cfg.u.c_l4.ip = ip_rule0;\r
-class_1 =  netcp_cfgAddClass(netapi_handle,\r
-                             &class_1_cfg,\r
-                             NULL,\r
-                             NETCP_CFG_ACTION_TO_SW,\r
-                             &err);\r
-if (err) {printf("addclass1 failed %d\n",err); exit(1);}\r
-\r
-\r
-//3rd classifier has a different IP and route\r
-class_2_cfg.u.c_l3_l4.ip_addr = &OurIp2;\r
-\r
-//create specialFlow for this classifier\r
-{\r
-Pktlib_HeapHandle heaps[2];\r
-int sizes[2];\r
-heaps[0]= specialSmall;\r
-heaps[1]= specialLarge;\r
-sizes[0]=256;\r
-sizes[1]=1600;\r
-specialFlow = netcp_cfgAddFlow( netapi_handle,\r
-                               2,\r
-                                heaps,\r
-                                sizes,\r
-                                &err);\r
-if (err) {printf("add flow failed\n", err); exit(1);}\r
-}\r
-//special route for this classifier:  different flow + destination q\r
-class2_route.p_dest_q = netcp_rx_chan2;\r
-class2_route.p_flow = specialFlow;\r
-class_2 = netcp_cfgAddClass(netapi_handle,\r
-                            &class_2_cfg,\r
-                            (void*) &class2_route,\r
-                            NETCP_CFG_ACTION_TO_SW,\r
-                            &err);\r
-if (err) {printf("addclass2 failed %d\n",err); exit(1);}\r
-#endif\r
-\r
-//security stuff \r
-ourRXKeyParams.pEncKey = &ourEncrKey[0];\r
-ourRXKeyParams.pAuthKey = &ourAuthKey[0];\r
-memcpy(&rx_sa.src, &TheirIp4IPSEC,4);\r
-memcpy(&rx_sa.dst, &OurIp4IPSEC,4);\r
-\r
-#if 1\r
-rx_tunnel = netapi_secAddSA( netapi_handle,\r
-                 0, //iface #0 \r
-                &rx_sa,\r
-                &ourRXKeyParams,\r
-#ifdef IPSEC_MODE_RX_SIDEBAND\r
-               NETAPI_SEC_SA_SIDEBAND,\r
-#else\r
-                NETAPI_SEC_SA_INFLOW,  //USE inflow mode\r
-#endif\r
-                NULL,  //use default route \r
-               &rx_data_mode_handle,\r
-               &rx_inflow_mode_handle,\r
-               &err);\r
-if (err) {printf("addRxSa failed %d\n",err); exit(1);}\r
-\r
-#ifdef IPSEC_MODE_RX_INFLOW\r
-//assume inner and outer ip is the same\r
-rx_policy= netapi_secAddRxPolicy( netapi_handle,\r
-                         rx_tunnel,  //link to tunnel above\r
-                         4,         //ipv4\r
-                         &TheirIp4IPSEC, //src -> them\r
-                        &OurIp4IPSEC,  //dst -> us\r
-                        NULL,  // no qualifiers\r
-                        NULL,  //default route\r
-                         &err);\r
-if (err) {printf("addSaPolicy failed %d\n",err); exit(1);}\r
-#else \r
-rx_policy = 0;\r
-#endif\r
-#endif\r
-\r
-//tx SA\r
-//security stuff \r
-ourTXKeyParams.pEncKey = &ourEncrKey[0];\r
-ourTXKeyParams.pAuthKey = &ourAuthKey[0];\r
-memcpy(&tx_sa.src, &OurIp4IPSEC,4);\r
-memcpy(&tx_sa.dst, &TheirIp4IPSEC,4);\r
-tx_tunnel = netapi_secAddSA( netapi_handle,\r
-                 0, //iface #0 \r
-                &tx_sa,\r
-                &ourTXKeyParams,\r
-#ifdef IPSEC_MODE_TX_SIDEBAND\r
-                NETAPI_SEC_SA_SIDEBAND,\r
-#else\r
-                NETAPI_SEC_SA_INFLOW,  //USE inflow mode\r
-#endif\r
-                NULL,  //use default route \r
-                &tx_data_mode_handle,\r
-                &tx_inflow_mode_handle,\r
-                &err);\r
-if (err) {printf("addTxSa failed %d\n",err); exit(1);}\r
-\r
-\r
-\r
-//timers\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
-netcp_cfgReqStats(netapi_handle, our_stats_cb, 1,&err);\r
-if (err!=0) {printf("stats req failed\n");}\r
-\r
-/*********************************************/\r
-/*****************end NETAPI STARTUP**********/\r
-/*********************************************/\r
-\r
-\r
-/********************************************\r
-* Basic pkt loopback test\r
-*********************************************/\r
-printf("...runnining pure push/pop benchmark\n");\r
-our_pktio_bench(100);\r
-\r
-\r
-\r
-\r
-\r
-/**************unused stuff******************/\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
-our_stats_cb(netapi_handle, NULL);\r
-\r
-/*************************************************\r
- ************CLEAN UP****************************\r
- ************************************************/\r
-\r
-//delete Classifiers\r
-netcp_cfgDelClass(netapi_handle, class_0, &err); \r
-netcp_cfgDelClass(netapi_handle, class_1, &err); \r
-netcp_cfgDelClass(netapi_handle, class_2, &err); \r
-\r
-//delete flow \r
-netcp_cfgDelFlow(netapi_handle, specialFlow, &err);\r
-\r
-#if 1\r
-//delete policy\r
-if (rx_policy)\r
-       netapi_secDelRxPolicy(netapi_handle, rx_policy, &err);\r
-\r
-//delete tunnels\r
-netapi_secDelSA(netapi_handle, 0, rx_tunnel, &err);\r
-netapi_secDelSA(netapi_handle, 0, tx_tunnel, &err);\r
-#endif\r
-\r
-//delete IPs and MAC Interfacess\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
-\r
-//close pktio channels we opened\r
-pktio_close(netcp_tx_chan ,&err);\r
-pktio_close(netcp_rx_chan ,&err);\r
-pktio_close(netcp_sb_tx_chan ,&err);\r
-pktio_close(netcp_sb_rx_chan ,&err);\r
-\r
-//clear pktio channel we created\r
-pktio_control(our_chan, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channel_control, &err);\r
-pktio_control(netcp_rx_chan2, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channel_control, &err);\r
-\r
-//delete pktio channels we created\r
-pktio_delete(our_chan, &err);\r
-pktio_delete(netcp_rx_chan2,&err);\r
-\r
-netapi_shutdown(netapi_handle);\r
-\r
-}\r
+/******************************************
+ * 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.
+
+ *****************************************/
+//#define NET_TEST_ENABLE_SIDE_BAND_LOW_LEVEL_API
+#ifdef NET_TEST_ENABLE_SIDE_BAND_LOW_LEVEL_API
+#define NWAL_ENABLE_SA
+#endif
+
+#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>
+#include "net_test.h"
+#include <ti/drv/sa/salld.h>
+//#define EXPERIMENTAL
+#ifdef EXPERIMENTAL
+#include "router.c"
+Trie * our_router;
+
+
+
+
+OUR_ROUTE_T routes[MAX_ROUTES]=
+{
+{0,{0xD4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x14,0x02,0x08,0x00},0},
+{0,{0x00,0x00,0x0,0x00,0x0,0x0, 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00},0},
+{0,{0xD4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x14,0x02,0x08,0x00},0},
+{0,{0x00,0x15,0x60,0xa1,0xf7,0xbe, 0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00},0},
+{0,{0xd4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00},0}};
+
+unsigned int ip[MAX_ROUTES]={BE(0x0a0100c8),BE(0x0a00000a),BE(0x0a02000a),BE(0xc0a8010a),BE(0x9eda6719)};
+
+#endif
+//#define TEST_TIMERS
+
+/*************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");
+}
+void dump_header(unsigned long *p, int n, int a, int r)
+{
+   printf("--------dump of header %d %x appID=%x flag1=%x\n", n, (int) p,a,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]);
+   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("> %x %x %x %x %x %x %x %x\n",p[16],p[17],p[18],p[19],p[20],p[21],p[22],p[23]);
+   printf("> %x %x %x %x %x %x %x %x\n",p[24],p[25],p[26],p[27],p[28],p[29],p[30],p[31]);
+   printf("-----------------------------\n");
+}
+
+
+static void  netapi_dump_buf
+(
+    unsigned long *                      buf,
+    uint32_t                      buf_length
+)
+{
+    uint8_t                       count = 0;
+    uint16_t                      dump_size;
+    uint8_t*                     tmp_buf;
+    uint8_t                       row_count;
+    static uint8_t                first = 0;
+
+    //if(first > 2) return;
+
+    //first++;
+
+    dump_size = buf_length ;
+
+    tmp_buf = (uint8_t *)(buf);
+
+    printf("netapi *:  - 8 bit word hex Length: %d Start \n",buf_length);
+    do
+    {
+        row_count = (dump_size - count);
+
+        if(row_count == 0)
+        {
+            break;
+        }
+
+        if(row_count > 4)
+        {
+            row_count = 4;
+        }
+
+        switch (row_count)
+        {
+            case 4:
+            {
+                printf("netapi *:%02d : %02x    %02x    %02x    %02x \n",
+                      count,tmp_buf[0],tmp_buf[1],tmp_buf[2],tmp_buf[3]);
+                break;
+            }
+            case 3:
+            {
+                printf("netapi *: %02d : %02x    %02x    %02x \n",
+                      count,tmp_buf[0],tmp_buf[1],tmp_buf[2]);
+                break;
+            }
+
+            case 2:
+            {
+                printf("netapi *: %02d : %02x    %02x \n",
+                      count,tmp_buf[0],tmp_buf[1]);
+                break;
+            }
+
+            case 1:
+            {
+                printf("netapi *: %02d : %02x \n",
+                      count,tmp_buf[0]);
+                break;
+            }
+
+            default:
+            {
+                /* Should never reach here */
+                printf("netapi *: Internal Error in netapi_dump_buf().Row Count: %d \n",
+                    row_count);
+                return;
+            }
+        }
+
+        tmp_buf = tmp_buf + row_count;
+        count = count +  row_count;
+
+    }while(count < dump_size);
+
+    printf("netapi *:  - Byte hex Dump End \n");
+
+}
+
+
+/*****************************************/
+
+
+//************for multi pkt burst  xfer test in loopback mode
+#define TX_BURST 700 
+int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;
+nwalTxPSCmdInfo_t   flowPSCmdInfo;
+nwal_RetValue       nwalRetVal;
+
+/* Local Per Process default resourcese maintained at NWAL */
+nwalLocCxtInfo_t    nwalLocCxt;
+
+//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
+
+};
+
+char    input_file_name[] = "net_test_config.txt";
+#define MAX_LINE_LENGTH 40
+
+#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
+
+void example_fast_poll( PKTIO_HANDLE_T * p_pktio, int max_pkts);
+void example_fast_pushpop(Pktlib_HeapHandle p_heap, int ntrials);
+
+void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
+                         PKTIO_METADATA_T meta[], int n_pkts,
+                         uint64_t ts );
+
+
+//#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 */
+
+
+
+/* net test default configuration */
+netTestConfig_t config =
+{
+    {0x00,0x01,0x02,0x03,0x05,0x05},
+    {0x00,0x01,0x02,0x03,0x05,0x06},
+    {10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {10, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    {192,168 , 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    {192,168 , 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    IPSEC_MODE_RX_SIDEBAND,
+    IPSEC_MODE_TX_SIDEBAND,
+    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;
+Trie *p_trie_sa;
+HEAD_T pkts[NP];
+#define PERSLOW  10  //% of pkts that will not be fastpath'd 
+int perslow= PERSLOW;
+
+/*******************************************
+ *************NETAPI OBJECTS***************
+ *****************************************/
+static NETAPI_CFG_T our_netapi_default_cfg=
+{
+TUNE_NETAPI_PERM_MEM_SZ,
+128,  //start of packet offset for hw to place data on rx for default flow
+TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
+TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
+TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
+64, //#descriptors w/o buffers in default heap
+TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
+128   ,  //tail room
+256      //extra room 
+};
+
+Pktlib_HeapHandle OurHeap;
+Pktlib_HeapHandle specialSmall;
+Pktlib_HeapHandle specialLarge;
+
+PKTIO_HANDLE_T *our_chan;
+PKTIO_HANDLE_T *netcp_rx_chan;
+PKTIO_HANDLE_T *netcp_rx_chan2;
+PKTIO_HANDLE_T *netcp_tx_chan;
+PKTIO_HANDLE_T *netcp_sb_tx_chan;
+PKTIO_HANDLE_T *netcp_sb_rx_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_rx_cfg2={PKTIO_R, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8};
+PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
+PKTIO_CFG_T netcp_sb_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
+PKTIO_CFG_T netcp_sb_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, 5000000  //every 5000000 poll loops
+};
+void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
+HPLIB_TIMER_GROUP_HANDLE_T ourTimerBlock; 
+HPLIB_TIMER_T t1;
+HPLIB_TIMER_T t2;
+HPLIB_TIMER_T t3;
+
+void our_timer_cb( HPLIB_TIMER_GROUP_HANDLE_T th,
+        int n_fired,     //# timers fired
+        HPLIB_TIMER_LIST_T fired_list,
+        uint64_t currentTime);
+
+NETCP_CFG_IP_T ip_rule0;
+NETCP_CFG_IP_T ip_rule1;
+NETCP_CFG_CLASS_T class_0;
+NETCP_CFG_CLASS_T class_1;
+NETCP_CFG_CLASS_T class_2;
+NETCP_CFG_FLOW_HANDLE_T specialFlow;
+
+
+NETCP_CFG_CLASSIFIER_T class_0_cfg=
+{
+   NETCP_CFG_CLASS_TYPE_L4,
+   {
+        {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2500}}
+   }
+};
+
+NETCP_CFG_CLASSIFIER_T class_1_cfg=
+{
+    NETCP_CFG_CLASS_TYPE_L4,
+    {
+        {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2502}}
+    }
+};
+
+NETCP_CFG_ROUTE_T  class2_route=
+{
+NULL, NULL  //* to be filled in
+};
+NETCP_CFG_CLASSIFIER_T class_2_cfg=  
+{
+   NETCP_CFG_CLASS_TYPE_L3_L4,
+   {
+        {0,  4 ,0/*fill in below*/ , NULL, NULL,          //L2/L3
+           NWAL_APP_PLOAD_PROTO_UDP, {2504}}   //L4
+   }
+};
+
+PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};
+
+/* security objects. (for loopback mode) */
+netTestSA_t sa_info[6];
+int netapi_algorithm_set = 0;
+int netapi_sec_sa_mode = 2;
+
+NETCP_CFG_IPSEC_POLICY_T rx_policy[4];
+
+
+
+NETAPI_SEC_SA_INFO_T rx_sa [7] = {
+{
+    NWAL_SA_DIR_INBOUND,
+    0x11111111,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
+    64,/* replayWindow */
+    NWAL_SA_AALG_HMAC_SHA1,
+    NWAL_SA_EALG_AES_CBC,
+    0,0  //na
+},
+{
+    NWAL_SA_DIR_INBOUND,
+    0x22222222,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
+    64,/* replayWindow */
+    NWAL_SA_AALG_HMAC_SHA2_256,
+    NWAL_SA_EALG_AES_CTR,
+    0,0  //na
+},
+{
+    NWAL_SA_DIR_INBOUND,
+    0x33333333,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
+    0,/* replayWindow */
+    NWAL_SA_AALG_NULL,
+    NWAL_SA_EALG_3DES_CBC,
+    0,0  //na
+},
+{
+    NWAL_SA_DIR_INBOUND,
+    0x44444444,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
+    64,/* replayWindow */
+    NWAL_SA_AALG_HMAC_MD5,
+    NWAL_SA_EALG_NULL,
+    0,0  //na
+},
+{
+    NWAL_SA_DIR_INBOUND,
+    0x55555555,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
+    64,/* replayWindow */
+    NWAL_SA_AALG_NULL,
+    NWAL_SA_EALG_AES_GCM,
+    0,0  //na
+},
+{
+    NWAL_SA_DIR_INBOUND,
+    0x66666666,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
+    64,/* replayWindow */
+    NWAL_SA_AALG_NULL,
+    NWAL_SA_EALG_AES_CCM,
+    0,0  //na
+},
+{
+    NWAL_SA_DIR_INBOUND,
+    0x77777777,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
+    64,/* replayWindow */
+    NWAL_SA_AALG_GMAC,
+    NWAL_SA_EALG_NULL,
+    0,0  //na
+}
+};
+
+/*tx */
+NETAPI_SEC_SA_INFO_T tx_sa[7]= {
+{
+    NWAL_SA_DIR_OUTBOUND,
+    0x11111111,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (us) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (them) -> set below*/
+    64, /* NA replayWindow */
+    NWAL_SA_AALG_HMAC_SHA1,
+    NWAL_SA_EALG_AES_CBC,
+    0,0  //seq no
+},
+    {
+    NWAL_SA_DIR_OUTBOUND,
+    0x22222222,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (us) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (them) -> set below*/
+    64, /* NA replayWindow */
+    NWAL_SA_AALG_HMAC_SHA2_256,
+    NWAL_SA_EALG_AES_CTR,
+    0,0  //seq no
+},
+{
+    NWAL_SA_DIR_OUTBOUND,
+    0x33333333,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (us) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (them) -> set below*/
+    0, /* NA replayWindow */
+    NWAL_SA_AALG_NULL,
+    NWAL_SA_EALG_3DES_CBC,
+    0,0  //seq no
+},
+{
+    NWAL_SA_DIR_OUTBOUND,
+    0x44444444,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (us) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (them) -> set below*/
+    64, /* NA replayWindow */
+    NWAL_SA_AALG_HMAC_MD5,
+    NWAL_SA_EALG_NULL,
+},
+{
+    NWAL_SA_DIR_OUTBOUND,
+    0x55555555,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
+    64,/* replayWindow */
+    NWAL_SA_AALG_NULL,
+    NWAL_SA_EALG_AES_GCM,
+    0,0  //na
+},
+{
+    NWAL_SA_DIR_OUTBOUND,
+    0x66666666,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
+    64,/* replayWindow */
+    NWAL_SA_AALG_NULL,
+    NWAL_SA_EALG_AES_CCM,
+    0,0  //na
+},
+{
+    NWAL_SA_DIR_OUTBOUND,
+    0x77777777,  //spi
+    nwal_IpSecProtoESP, //ESP mode
+    nwal_SA_MODE_TUNNEL,  //tunnel mode
+    nwal_IPV4, //v4
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
+    { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
+    64,/* replayWindow */
+    NWAL_SA_AALG_GMAC,
+    NWAL_SA_EALG_NULL,
+    0,0  //na
+}
+};
+
+static nwalSecKeyParams_t ourTXKeyParams[7] ={
+{
+    16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/
+    20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA1 */
+    NULL, //set below
+    NULL, //set below
+},
+{
+    20, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_AES_CTR and 0 bytes Salt*/
+    32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */
+    NULL, //set below
+    NULL, //set below
+},
+{
+    24, /* encKeySize: DES-CBC: 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/
+    0, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */
+    NULL, //set below
+    NULL, //set below
+},
+{
+    0, /* NULL*/
+    16, /* MD5, 16 bytes */
+    NULL, //set below
+    NULL, //set below
+},
+{
+    20, /* encKeySize: GCM 16 bytes Encryption Key and 4 bytes Salt */
+    0, /* macKeySize: 0*/
+    NULL, //set below
+    NULL, //set below
+},
+{
+    19, /* encKeySize: CTR 16 bytes Encryption Key and 3 bytes Salt : 24 bytes:NWAL_SA_EALG_AES_CTR and 0 bytes Salt*/
+    0, /* macKeySize 0*/
+    NULL, //set below
+    NULL, //set below
+},
+{
+    0, /* encKeySize: CTR 16 bytes Encryption Key and 3 bytes Salt : 24 bytes:NWAL_SA_EALG_AES_CTR and 0 bytes Salt*/
+    24, /* macKeySize 0*/
+    NULL, //set below
+    NULL, //set below
+}
+};
+
+/* these keys are for aes-ctr and hmac sha2_256 */
+static nwalSecKeyParams_t ourRXKeyParams[7] ={
+{
+    16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/
+    20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA1 */
+    NULL, //set below
+    NULL, //set below
+},
+{
+    20, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt */
+    32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */
+    NULL, //set below
+    NULL, //set below
+},
+{
+    24, /* encKeySize: DES-CBC: 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/
+    0, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */
+    NULL, //set below
+    NULL, //set below
+},
+{
+    0, /* NWAL_SA_EALG_NULL*/
+    16, /* NWAL_SA_AALG_HMAC_MD5, 16 bytes */
+    NULL, //set below
+    NULL, //set below
+},
+{
+    20, /* encKeySize: GCM 16 bytes Encryption Key and 4 bytes Salt */
+    0, /* macKeySize: 0*/
+    NULL, //set below
+    NULL, //set below
+},
+{
+    19, /* encKeySize: CTR 16 bytes Encryption Key and 3 bytes Salt t*/
+    0, /* macKeySize 0*/
+    NULL, //set below
+    NULL, //set below
+},
+{
+    0, /* encKeySize: CTR 16 bytes Encryption Key and 3 bytes Salt : 24 bytes:NWAL_SA_EALG_AES_CTR and 0 bytes Salt*/
+    24, /* macKeySize 0*/
+    NULL, //set below
+    NULL, //set below
+}
+};
+
+
+static uint8_t ourAuthKey[36] =
+        {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+         0x20, 0x21, 0x22, 0x23 };
+;
+
+static uint8_t ourEncrKey[36] = 
+        {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
+         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
+         0x30, 0x31, 0x32, 0x33 }; 
+
+
+/*************************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; 
+    if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC)
+    {
+    stats.sec_rx++;
+    }
+    if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC_POLICY)
+    {
+    stats.secp_rx++;
+    }
+
+    if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_CLASS)
+    {
+        int c= ((unsigned int)p_meta->u.rx_meta->appId >>8)&0xffff;
+    if (c==0)  stats.n_class0_rx +=1;
+    else if (c==1) stats.n_class1_rx +=1;
+    else if (c==2) stats.n_class2_rx +=1;
+    else printf("**NET_TEST RX -unknown class: %x\n",  p_meta->u.rx_meta->appId);
+}
+}
+
+ 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);
+}
+}
+
+//measurement test points
+unsigned int vv1;
+unsigned int vv2;
+unsigned int vv3;
+unsigned int vv4;
+unsigned int vv5;
+unsigned int vv6;
+//these are updated by pktio.
+#ifdef PKTIO_GET_BENCHMARK
+extern unsigned int vv7p;
+extern unsigned int vv8p;
+extern unsigned int vv9p;
+extern unsigned int vv10p;
+extern unsigned int vv11p;
+extern unsigned int vv12p;
+
+extern unsigned int vv13p;  //rcv path
+extern unsigned int vv14p;
+extern unsigned int vv15p;
+#endif
+
+unsigned int vv11;
+
+extern unsigned int nwal_prof1,nwal_prof2,nwal_prof3,nwal_prof4,nwal_prof5,nwal_prof6;
+
+//#define REASSEMBLE_BENCH
+#ifdef REASSEMBLE_BENCH
+#include <ti/drv/pa/example/reassemLib/reassemLib.h>
+/*--------------reassembly benchmark--------------------------------*/
+void our_reassemble_bench(int nfrags)
+{
+paIPReassemblyConfig_t Config={5,128,10000 };
+int i,j;
+int len;
+Ti_Pkt tip;
+char *buffer;
+unsigned long v1;
+unsigned long v2;
+unsigned long sum1=0;
+unsigned long sum2=0;
+paEx_reassemLibInit(&Config);
+for(j=0;j<200/nfrags;j++)
+{
+  for(i=0;i<nfrags;i++)
+  {
+    short temp;
+    tip=Pktlib_allocPacket(OurHeap,PKT_LEN);
+    Pktlib_getDataBuffer(tip,(uint8_t**)&buffer,&len);
+    memcpy(&buffer[0],&testPkt[14],20); //IP header
+    if (i < (nfrags-1)) buffer[6] = 0x20;
+    temp = i*40; 
+    buffer[6]|= (temp&0x1f00)>>8;
+    buffer[7]= (temp&0xff);
+    temp = 20+40*8; 
+    buffer[2]= (temp&0xff00)>>8;
+    buffer[3]= (temp&0xff);
+    Pktlib_setPacketLen(tip, temp);
+    v1= hplib_mUtil_GetTickCount();
+    paEx_reassemLibProc(tip, 0xffff);
+    v2= hplib_mUtil_GetTickCount();
+    sum1+= v2-v1;
+  }
+  sum2 += v2-v1;
+}
+printf("reasssembly test:  %d trials, %d frags/pkt  %d cycles/frag %d cycles/last frag\n",j,nfrags, sum1/(j*nfrags), sum2/(j));
+}
+#endif
+
+/*--------------basic pktio send/recv benchmark----------------------*/
+unsigned int timings[10];
+void our_pktio_bench(int ntrials)
+{
+int i;
+#define NBATCH 8
+Ti_Pkt tip;
+unsigned char * pData;
+int len;
+int n;
+int err;
+int sum =0;
+
+   Osal_cache_op_measure_reset();
+   for(i=0;i<10;i++) timings[i]=0;
+   printf("calibration loop .. ");
+   for(i=0;i<1000;i++)
+   {
+   vv1= hplib_mUtil_GetTickCount();
+   vv2= hplib_mUtil_GetTickCount();
+   sum+=(vv2-vv1);
+   }
+   printf(" accuracy = +- %d cycles\n", sum/1000);
+   sleep(1);
+  
+PKTIO_METADATA_T meta[10]={0};
+//send single, recv single
+for(i=0;i<ntrials;i++)
+{
+   vv1= hplib_mUtil_GetTickCount();
+   tip=Pktlib_allocPacket(OurHeap,PKT_LEN);
+   vv2= hplib_mUtil_GetTickCount();
+   Pktlib_getDataBuffer(tip,&pData,&len);
+   vv3= hplib_mUtil_GetTickCount();
+   pktio_send(our_chan,tip,&meta[0],&err);
+   vv4= hplib_mUtil_GetTickCount();
+   n=pktio_poll(our_chan,NULL , &err);
+   vv5=   hplib_mUtil_GetTickCount();
+   timings[0]+=(vv6-vv4);
+   timings[1]+=(vv5-vv4);
+   timings[3]+=(vv4-vv3); 
+   timings[5]+=(vv3-vv1);
+   timings[8]+=(vv11-vv6);
+
+#ifdef PKTIO_GET_BENCHMARK
+   timings[2]+=(vv7p-vv4);
+   timings[4]+=(vv8p-vv3);
+   timings[6]+=(vv9p-vv8p);
+   timings[7]+=(vv10p-vv7p);
+#endif
+}
+
+#ifdef PKTIO_GET_BENCHMARK
+   printf("pktio bench. rx=%d (wcb%d) (toqm%d) tx=%d (toqm%d) alloc=%d qpush=%d qpop=%d free=%d\n", timings[0]/ntrials,
+           timings[1]/ntrials, timings[2]/ntrials,timings[3]/ntrials, timings[4]/ntrials,timings[5]/ntrials,
+           timings[6]/ntrials,timings[7]/ntrials, timings[8]/ntrials );
+   {
+       unsigned int ccycles;
+       int n_c_ops;
+       ccycles =Osal_cache_op_measure(&n_c_ops);
+       printf("n_c_ops=%d cache_op_time=%d (total) = %d (pp)\n", n_c_ops, ccycles,  n_c_ops? (ccycles/(n_c_ops)) : 0);
+   }
+#endif
+
+}
+/*-----------test driver: gen an input pkt------- */
+//char buffer[sizeof(HEAD_T)+PKT_LEN];
+Ti_Pkt * get_pkt(int n, unsigned int *p_len, Pktlib_HeapHandle heap2use, int size, unsigned char * buf2cpy, int copy_size)
+{
+   int ind;
+   long long temp;
+   Ti_Pkt * b;
+   char * buffer;
+   unsigned int len;
+
+  if (pktloopback==0)
+  {
+       if (n>=TX_BURST) return NULL;   //just gen pkts to warm swtich, so that it knows
+                                //our mac is valid
+  }  
+  b=Pktlib_allocPacket(heap2use,size);
+  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 (!buffer) 
+    {printf("net_test: get_pkt() heap returned empty buffer %d \n", n); return NULL;};
+
+#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], buf2cpy, copy_size);
+    *p_len = copy_size;
+}
+    return b; 
+}
+
+static int eof=0;
+/*--------------------------------------------------------------
+ *----------utility to flip a packet and send 
+ *--------------------back to source----------------------------
+ *                   flag=1 => ipsec
+ *--------------------------------------------------------------*/
+void flip_and_send_pkt(Ti_Pkt *tip,  unsigned char * p_pkt, int len, int flag)
+{
+    unsigned char mac_temp[6];
+    unsigned char ip_temp[4];
+    unsigned char new_dest_port[2]={0x75,0x30};  // 30000
+    uint16_t blah; 
+    uint16_t i=1;   /* for testing only */
+
+    uint8_t *p_spi; 
+    netTestSA_t * p_sa_info;
+    uint8_t p_iv[16];
+    uint8_t p_add[8];
+    Cppi_HostDesc*          pPloadDesc;
+
+    printf("flip_and_send_pkt()\n");
+              //netapi_dump_buf((long*)p_pkt,len);
+    Pktlib_setPacketLen(tip,len);
+    //flip the mac address
+    memcpy(&mac_temp,&p_pkt[0],6);
+    memcpy(&p_pkt[0],&p_pkt[6],6);
+    memcpy(&p_pkt[6],&mac_temp,6);
+    //memcpy(&p_pkt[0],real_mac_header,6); //for testing to wireshark pc
+
+    //flip the ip  (outer in case of ipsec)
+    memcpy(&ip_temp, &p_pkt[14+12],4);
+    memcpy(&p_pkt[14+12],&p_pkt[14+12+4],4);
+    memcpy(&p_pkt[14+12+4],&ip_temp,4);
+
+    //outer checksum to 0
+    if (!flag) 
+    {
+        memset(&p_pkt[14+10],0,2);
+    }
+
+    //inner ip &udp for ipsec
+    if (flag) 
+    {
+        p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]);
+        p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa, (char *)p_spi ,4);
+        if (p_sa_info == NULL)
+        {
+            printf("flip_and_send_pkt(): trie_lookup() failed\n");
+            return;
+        }
+        //just drop non-udp packet
+        if (p_pkt[p_sa_info->tx_payload_info.encOffset+9]!=0x11)
+        {
+            stats.n_new+=1;Pktlib_freePacket(tip); return;
+        }
+
+        /* flip inner IP */
+        memcpy(&ip_temp, &p_pkt[p_sa_info->tx_payload_info.encOffset+12],4);
+        memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+12],&p_pkt[p_sa_info->tx_payload_info.encOffset+12+4],4);
+        memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+12+4],&ip_temp,4);
+
+        /* setting udp ports */
+        memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+20+2],&new_dest_port[0],2);
+        memset(&p_pkt[p_sa_info->tx_payload_info.encOffset+20+6],0,2); //checksum
+
+        if (config.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND)
+        {
+            /* inner ip checksum : leave alone */
+            /* outer ip, set to 0 (we will compute on way out */
+            memset(&p_pkt[14+10],0,2);
+        }
+        else
+        {
+            //#else //inflow, don't touch outer , clear inner 
+            //DALmemset(&p_pkt[14+20+8+16+10],0,2); //inner checksum, we will compute on way out
+            //outer ip checksum : leave alone
+        }
+    }
+    else
+    {
+        memset(&p_pkt[14+20+6],0,2);//0 udp checksum (we will compute on way out
+        memcpy(&p_pkt[14+20+2],&new_dest_port[0],2);
+    }
+
+    /*IPSEC case */ 
+    if (flag)
+    {
+        if (config.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND)
+        //send to crypto for encryption
+        //12 byte auth tag
+        {
+            PKTIO_METADATA_T meta = {PKTIO_META_SB_TX,{0},0};
+            int err;
+            nwalDmTxPayloadInfo_t meta_tx={0};
+            meta.sa_handle=p_sa_info->tx_data_mode_handle;  //use TX SA context
+
+            memcpy(&meta_tx, &(p_sa_info->tx_payload_info), sizeof(nwalDmTxPayloadInfo_t));
+
+                meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -p_sa_info->auth_tag_size;
+                meta_tx.authSize = len - meta_tx.authOffset - p_sa_info->auth_tag_size;
+
+#if 1
+            printf("flip_and_send_pkt(): encOffset %d\n", meta_tx.encOffset);
+            printf("flip_and_send_pkt():authOffset %d\n", meta_tx.authOffset);
+            printf("flip_and_send_pkt(): encSize %d\n", meta_tx.encSize);
+            printf("flip_and_send_pkt(): authSize %d\n", meta_tx.authSize);
+#endif
+
+            meta_tx.pAuthIV=NULL;
+            meta_tx.aadSize=0;
+            meta_tx.pAad=NULL;
+            if (p_sa_info->cipherMode ==  NWAL_SA_EALG_AES_CTR)
+            {
+                memcpy(&p_iv[0], &ourEncrKey[16], 4);
+                memcpy(&p_iv[4], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
+                p_iv[12] = 0;
+                p_iv[13] = 0;
+                p_iv[14] = 0;
+                p_iv[15] = 1;
+                meta_tx.pEncIV = &p_iv[0];
+            }
+            else if ((p_sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
+                (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CCM))
+                {
+                        memcpy(&p_iv[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
+                        meta_tx.pEncIV = &p_iv[0];
+                        memcpy(&p_add[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN], 8);
+                        meta_tx.pAad= &p_add[0];
+                        meta_tx.aadSize = 8;
+                }
+            else if (p_sa_info->cipherMode ==  NWAL_SA_EALG_NULL)
+            {
+                meta_tx.pEncIV = NULL;
+            }
+            else
+            {
+                meta_tx.pEncIV = &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN ];
+            }
+            //meta_tx.authIvSize=0;
+
+            /* post it to netcp sb tx channel*/
+            meta_tx.appCtxId = (nwal_AppId)hplib_mUtil_GetTickCount();
+            meta.u.tx_sb_meta=&meta_tx;
+
+#ifdef NET_TEST_ENABLE_SIDE_BAND_LOW_LEVEL_API
+            /* Use the command label which was cached during create time
+            * Update the Queue to receive output packet from SA to the local 
+            * core Queue. Below information can be saved by application in 
+            * per process context to avoid API overhead per packet
+            * Application can use below rxSbSaQ for polling packets back from
+            * SA
+            */
+            nwalRetVal =  
+            nwal_getLocCxtInfo(PKTIO_GET_NWAL_INSTANCE(netcp_sb_tx_chan),
+                                                      &nwalLocCxt);
+            if(nwalRetVal == nwal_OK)
+            {
+                p_sa_info->tx_dmPSCmdInfo.rxSbSaQ = nwalLocCxt.rxSbSaQ;
+            }
+            nwal_mCmdDMUpdate(tip,
+                              &p_sa_info->tx_dmPSCmdInfo,
+                              meta_tx.appCtxId,
+                              meta_tx.encOffset,
+                              meta_tx.encSize,
+                              meta_tx.pEncIV,
+                              meta_tx.authOffset,
+                              meta_tx.authSize,
+                              meta_tx.pAuthIV,
+                              meta_tx.aadSize,
+                              meta_tx.pAad);
+            pPloadDesc = Pktlib_getDescFromPacket(tip);
+            pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
+            Qmss_queuePushDescSizeRaw(p_sa_info->tx_dmPSCmdInfo.txQueue,
+                                       pPloadDesc,
+                                       NWAL_DESC_SIZE);
+
+#else
+            printf("flip_and_send_pkt(): sending for encryption\n");
+           pktio_send(netcp_sb_tx_chan,tip,&meta,&err);
+#endif
+       }
+else
+ {
+  //inflow tx
+  //send pkt directly, asking for IP and UDP checksum offloads AND IPSEC to be applied
+           PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};
+           int err;
+           nwalTxPktInfo_t meta_tx={0};
+#define USE_COPY
+#ifdef USE_COPY
+//debug:  see if re-using RX descriptor for TX is causing our SA lockup
+{
+  int new_len=0;
+  Ti_Pkt new_tip =  get_pkt(0, &new_len, specialLarge , len+10 , &p_pkt[0]   , len);
+  if (!new_tip)
+  {
+     printf("net_test> new_tip NULL\n");
+  }
+  else
+  {
+    Pktlib_setPacketLen(new_tip,new_len);
+    Pktlib_freePacket(tip);
+    tip=new_tip;  
+    Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&new_len);  //reset p_pkt to point to new buffer as its used below
+    Cppi_setTimeStamp (Cppi_DescType_HOST, (Cppi_Desc *) tip,stats.sec_tx); 
+  }
+}
+if (len <1500)  
+{
+  eof+=1;
+}
+#endif
+           meta.sa_handle=p_sa_info->tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied
+           //meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_META_DATA_VALID );
+           meta_tx.txFlag1 = p_sa_info->tx_pkt_info.txFlag1;
+           meta_tx.enetPort=0;
+           //meta_tx.saOffBytes=14+20;  
+           meta_tx.saOffBytes=  p_sa_info->tx_pkt_info.saOffBytes;
+           meta_tx.saPayloadLen=len-14-20;   //don't include tag, mac and outer header
+           //meta_tx.startOffset = 0;
+           meta_tx.startOffset = p_sa_info->tx_pkt_info.startOffset;
+           //meta_tx.ipOffBytes = 14+20+8+16;   //to inner header
+           meta_tx.ipOffBytes =p_sa_info->tx_payload_info.encOffset; 
+           //meta_tx.l4OffBytes = 14+20+8+16+20; //to L4
+           meta_tx.l4OffBytes = p_sa_info->tx_pkt_info.l4OffBytes;
+           meta_tx.l4HdrLen = p_sa_info->tx_pkt_info.l4HdrLen;
+           meta_tx.ploadLen = (unsigned) ((p_pkt[meta_tx.l4OffBytes+4]<<8)|p_pkt[meta_tx.l4OffBytes+4+1]) -8 ;
+           meta_tx.pseudoHdrChecksum =
+             test_utilGetIpv4PsudoChkSum(&p_pkt[meta_tx.ipOffBytes],8+ meta_tx.ploadLen);
+
+           /* post it to netcp tx channel*/
+           meta.u.tx_meta=&meta_tx;
+           if (stats.sec_tx<20) dump_descr((long *) tip, stats.sec_tx);
+           pktio_send(netcp_tx_chan,tip,&meta,&err);
+           stats.tx +=1;
+           stats.sec_tx +=1;
+     }
+}
+else  //non ipsec send pkt directly, asking for IP and UDP checksum ofload
+{
+           PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
+           int err;
+           nwalTxPktInfo_t meta_tx2={0};
+           meta2.sa_handle=nwal_HANDLE_INVALID;
+           meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
+           meta_tx2.startOffset = 0;
+           meta_tx2.ipOffBytes = 14;
+           meta_tx2.l4OffBytes = 14+20;
+           meta_tx2.l4HdrLen = 8;
+           meta_tx2.ploadLen = (unsigned) ((p_pkt[14+20+4]<<8)|p_pkt[14+20+4+1]) -8 ;
+           meta_tx2.pseudoHdrChecksum =
+             test_utilGetIpv4PsudoChkSum(&p_pkt[14],8+ meta_tx2.ploadLen);
+
+           /* post it to netcp tx channel*/
+           meta2.u.tx_meta=&meta_tx2;
+           pktio_send(netcp_tx_chan,tip,&meta2,&err);
+           stats.tx +=1;
+}
+}
+
+
+
+
+/***************************************
+ benchmark receive handler
+****************************************/
+void recv_cb_bench(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
+                         PKTIO_METADATA_T meta[], int n_pkts,
+                         uint64_t ts )
+{
+   int i;
+   vv6=   hplib_mUtil_GetTickCount();
+   for (i=0;i<n_pkts; i++) 
+   {
+     Pktlib_freePacket(p_recv[i]);
+   }
+   vv11 = hplib_mUtil_GetTickCount();
+}
+
+/****************************************************************************************/
+/******************SB Accelerator Callback PKT RECEIVE HANDLER *************************/
+/******************  Handles Decrypt and Encrypt operation callbacks ******************/
+/******************************************************************************************/
+void recv_sb_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;
+int tag_cmp=0;
+unsigned int hash[4];
+uint8_t *p_spi;
+netTestSA_t *p_sa_info;
+
+//nwal_AppId time;
+unsigned long time, delta_time;
+ /* 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
+
+
+         p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]);
+
+        p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa, (char *)p_spi ,4);
+        if (p_sa_info == NULL)
+        {
+            printf("recv_sb_cb(): trie_lookup failed\n");
+            continue;
+        }
+
+
+        //is this a decrypt (rx_tunnel) complete
+        if ((int)meta[i].u.rx_sb_meta->appId == p_sa_info->rx_tunnel)
+        {
+           
+            time = hplib_mUtil_GetTickCount();
+           delta_time = time -(unsigned long) meta[i].u.rx_sb_meta->appCtxId;
+            stats.total_decrypt_time += delta_time;
+            stats.sb_rx+=1;
+           //copy hash out of meta data (for some reason it needs endian conversion)
+           hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
+           hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
+           hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]);
+           hash[3]= htonl( meta[i].u.rx_sb_meta->pAuthTag[3]);
+           if(stats.sb_rx<=16)
+           {
+             char *tp = (char *) &hash[0];
+             //dump_header((long*)p_pkt, stats.sb_rx, (int)meta[i].u.rx_sb_meta->appId,0);
+#if 1
+             printf("decrypt complete: tag in pkt= %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x \n",
+                      p_pkt[len-16],p_pkt[len-15],p_pkt[len-14],p_pkt[len-13],
+                      p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],
+                      p_pkt[len-7],p_pkt[len-6],
+                      p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]);
+             printf("decrypt complete: tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x \n",
+                       tp[0],tp[1],tp[2],tp[3],tp[4],tp[5],
+                       tp[6],tp[7],tp[8],tp[9],tp[10],tp[11],tp[12],tp[13],tp[14],tp[15]);
+
+            // netapi_dump_buf((long*)p_pkt,len);
+#endif
+           }
+           //check tag 
+           printf("recv_sb_cb(); auth tag size %d\n", p_sa_info->auth_tag_size);
+           tag_cmp = memcmp(&p_pkt[len-p_sa_info->auth_tag_size],(char*) &hash[0],p_sa_info->auth_tag_size); //todo, really use meta->authTagLen
+           stats.n_auth_ok += !(tag_cmp);
+           
+            flip_and_send_pkt(tip, p_pkt, len,1);  //flip packet to echo back and send
+        }
+        //this is an encrypt (tx tunnel) complete
+        else if((int)meta[i].u.rx_sb_meta->appId== p_sa_info->tx_tunnel )
+        {
+           hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
+           hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
+           hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]);
+           hash[3]= htonl( meta[i].u.rx_sb_meta->pAuthTag[3]);
+           stats.sb_tx+=1;
+           if(stats.sb_tx<=16)
+           {
+             char *tp1 = (char *) &hash[0];
+             //dump_header((long*)p_pkt, stats.sb_tx, (int)meta[i].u.rx_sb_meta->appId,0);
+#if 1
+            printf("encrypt complete: tag in pkt=  %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x \n",
+                      p_pkt[len-16],p_pkt[len-15],p_pkt[len-14],p_pkt[len-13],
+                      p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],
+                      p_pkt[len-7],p_pkt[len-6],
+                      p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]);
+             printf("encrypt complete: tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x \n",
+                       tp1[0],tp1[1],tp1[2],tp1[3],tp1[4],tp1[5],
+                       tp1[6],tp1[7],tp1[8],tp1[9],tp1[10],tp1[11],tp1[12],tp1[13],tp1[14],tp1[15]);
+             //netapi_dump_buf((long*)p_pkt,len);
+#endif
+           }
+           //put the computed tag in the packet
+           memcpy(&p_pkt[len-p_sa_info->auth_tag_size],(char*)&hash[0],p_sa_info->auth_tag_size); //todo, really use meta->authTagLen
+          printf("recv_sb_cb(): dumping pkt after updating computed tag, len %d, auth tag size %d\n", len, p_sa_info->auth_tag_size);
+           //netapi_dump_buf(p_pkt, len);
+           {
+          PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
+           nwalTxPktInfo_t meta_tx={0};
+           // now send directly 
+           meta2.sa_handle=nwal_HANDLE_INVALID;
+           meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID);//only outer IP header checksum. no udp checksum possible since pkt is already encrypted
+           meta_tx.startOffset = 0;
+           meta_tx.ipOffBytes = netTest_MAC_HEADER_LEN;
+           //not used
+           meta_tx.l4OffBytes = 0;
+           meta_tx.l4HdrLen = 0;
+           meta_tx.ploadLen = 0;
+            time = hplib_mUtil_GetTickCount();
+            delta_time = time -(unsigned long) meta[i].u.rx_sb_meta->appCtxId;
+           stats.total_encrypt_time += delta_time;
+        
+
+           /* post it to netcp tx channel*/
+           meta2.u.tx_meta=&meta_tx;
+           printf("recv_sb_cb(): calling pktio send to send it to network\n");
+           pktio_send(netcp_tx_chan,tip,&meta2,&err);
+           hplib_CacheWbInv(p_pkt,len);
+           stats.tx +=1;
+           }
+        }
+        else printf("netapi recv_sb_cb: unknown appiD %x \n",meta[i].u.rx_sb_meta->appId );
+    }
+}
+
+/******************************************************/
+/******************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 = 0;
+    KEY_T key;
+    char * p_pkt;
+    HEAD_T * p_head;
+    HEAD_T temp_head;
+    netTestSA_t *p_sa_info;
+    uint8_t *p_spi;
+    uint8_t p_iv[16];
+    uint8_t p_add[8];
+    uint8_t p_add1[1500];
+    int16_t       retVal;
+                    nwalGlobCxtInfo_t   nwalGlobCxt;
+                    nwalLocCxtInfo_t    nwalLocCxt;
+
+    Cppi_HostDesc*          pPloadDesc;
+
+    p_head=&temp_head;
+
+    /* 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)-4;   /*real length, subtract mac trailer */
+        Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
+        Pktlib_setPacketLen(tip,len);
+        printf("recv_cb() packet len %d\n", len);
+
+        //debug: validate descriptor */
+        if(Pktlib_getNextPacket(tip) != 0) 
+        {
+            printf(" rcv_cb, nexpkt != NULL");
+        }
+
+        stats.rx+=1;
+
+#if 1
+        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
+#if 0
+        if(stats.rx<=16)
+        {
+            dump_header((long*)p_pkt, stats.rx, (int)meta[i].u.rx_meta->appId,meta[i].u.rx_meta->rxFlag1);
+             netapi_dump_buf((long*)p_pkt,len);
+        }
+#endif
+        /* check header */
+        memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
+
+        /* check for IPSEC packet, 0x32 is ESP tunnel mode */
+        if ((p_head->ip[2]&0x0000ff00)==0x00003200)
+        {
+            if (!check_header(p_head,&meta[i]))
+            {
+                printf("check header failed\n");
+                stats.n_bad+=1;Pktlib_freePacket(tip); 
+                continue;
+            }
+
+            //process IP SEC PACKET
+            if (config.ipsec_mode_rx == IPSEC_MODE_RX_SIDEBAND)
+            {
+#if 0
+                {
+                    
+                    uint8_t             count;
+                    NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) netapi_handle;
+
+
+
+
+                    printf("\n ------------- NWAL MODULE UNIT TEST BEGIN ------------- \n");
+                    retVal =
+                    nwal_getGlobCxtInfo(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
+                                        &nwalGlobCxt);
+                    if(retVal == nwal_OK)
+                    {
+                        printf("*******NWAL Global Context Info Dump Begin *******\n");
+                        printf("rxPaSaFlowId:%d,rxSaPaFlowId:%d rxDefPktQ:0x%x \n",
+                                       nwalGlobCxt.rxPaSaFlowId,nwalGlobCxt.rxSaPaFlowId,
+                                        nwalGlobCxt.rxDefPktQ);
+                        printf("defFlowQ:0x%x,passCppiHandle:0x%x extErr:%d \n",
+                                       nwalGlobCxt.defFlowQ,nwalGlobCxt.passCppiHandle,
+                                       nwalGlobCxt.extErr);
+                        for(count=0;count < nwalGlobCxt.numPaPDSPs;count++)
+                        {
+                            printf("NetCP PASS PDSP - %d Version:0x%x \n",
+                                           count,nwalGlobCxt.pdspVer[count]);
+                        }
+                        printf("*******NWAL Global Context Info Dump End *******\n\n");
+                    }
+                    printf(" calling nwal_getLocCxtInfo for tx channel\n");
+                    nwal_getLocCxtInfo(PKTIO_GET_NWAL_INSTANCE(netcp_sb_tx_chan),
+                                                      &nwalLocCxt);
+                    printf(" calling nwal_getLocCxtInfo for rx channel\n");
+                    nwal_getLocCxtInfo(PKTIO_GET_NWAL_INSTANCE(netcp_sb_rx_chan),
+                                                      &nwalLocCxt);
+
+                    
+              }
+#endif
+
+
+
+                
+                p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]);
+                 p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa, (char *)p_spi ,4);
+                if (p_sa_info == NULL)
+                {
+                    printf("recv_cb(): trie_lookup() failed\n");
+                    continue;
+                }
+
+                //ship to crypto for decrypt!!
+                //12 byte auth tag
+                PKTIO_METADATA_T meta2 = {PKTIO_META_SB_TX,{0},0};
+                nwalDmTxPayloadInfo_t meta_tx={0};
+                meta2.sa_handle=p_sa_info->rx_data_mode_handle;
+
+                memcpy(&meta_tx, &(p_sa_info->tx_payload_info), sizeof(nwalDmTxPayloadInfo_t));
+
+                //meta_tx.ploadLen = len;
+
+
+
+                    meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -p_sa_info->auth_tag_size;
+                    meta_tx.authSize = len - meta_tx.authOffset - p_sa_info->auth_tag_size;
+
+
+
+#if 1
+                printf("recv_cb(): packet length %d\n", len);
+                printf("recv_cb(): encOffset %d\n", meta_tx.encOffset);
+                printf("recv_cb():authOffset %d\n", meta_tx.authOffset);
+                printf("recv_cb(): encSize %d\n", meta_tx.encSize);
+                printf("recv_cb(): authSize %d\n", meta_tx.authSize);
+#endif
+
+                if (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CTR)
+                {
+                    memcpy(&p_iv[0], &ourEncrKey[16], 4);
+                    memcpy(&p_iv[4], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
+                    p_iv[12] = 0;
+                    p_iv[13] = 0;
+                    p_iv[14] = 0;
+                    p_iv[15] = 1;
+                    meta_tx.pEncIV = &p_iv[0];
+                 
+                }
+                else if ((p_sa_info->cipherMode == NWAL_SA_EALG_AES_GCM)  ||
+                            (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CCM))
+                {
+                        memcpy(&p_iv[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
+                        meta_tx.pEncIV = &p_iv[0];
+                        /* aad is the ESP header which is 8 bytes */
+                        memcpy(&p_add[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN], 8);
+                        meta_tx.pAad= &p_add[0];
+                        meta_tx.aadSize = 8;
+                }
+                else if (p_sa_info->cipherMode ==  NWAL_SA_EALG_NULL)
+                {
+                    meta_tx.pEncIV = NULL;
+                }
+                else
+                {
+                    meta_tx.pEncIV = &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN ];
+                }
+               
+                meta_tx.appCtxId = (nwal_AppId)hplib_mUtil_GetTickCount();
+                //printf("recv_cb appCtxId: %lu\n", meta_tx.appCtxId);
+
+                /* post it to netcp sb tx channel*/
+            meta2.u.tx_sb_meta=&meta_tx;
+
+/* TODO: Move the following ifdef code into ptkio_sendDM */
+#ifdef NET_TEST_ENABLE_SIDE_BAND_LOW_LEVEL_API
+            /* Use the command label which was cached during create time
+            * Update the Queue to receive output packet from SA to the local 
+            * core Queue. Below information can be saved by application in 
+            * per process context to avoid API overhead per packet
+            * Application can use below rxSbSaQ for polling packets back from
+            * SA
+            */
+            nwalRetVal =  
+            nwal_getLocCxtInfo(PKTIO_GET_NWAL_INSTANCE(netcp_sb_tx_chan),
+                                                      &nwalLocCxt);
+            if(nwalRetVal == nwal_OK)
+            {
+                p_sa_info->rx_dmPSCmdInfo.rxSbSaQ = nwalLocCxt.rxSbSaQ;
+            }
+            nwal_mCmdDMUpdate(tip,
+                              &p_sa_info->rx_dmPSCmdInfo,
+                              meta_tx.appCtxId,
+                              meta_tx.encOffset,
+                              meta_tx.encSize,
+                              meta_tx.pEncIV,
+                              meta_tx.authOffset,
+                              meta_tx.authSize,
+                              meta_tx.pAuthIV,
+                              meta_tx.aadSize,
+                              meta_tx.pAad);
+            pPloadDesc = Pktlib_getDescFromPacket(tip);
+            pPloadDesc = Qmss_osalConvertDescVirtToPhy(pPloadDesc);
+            Qmss_queuePushDescSizeRaw(p_sa_info->rx_dmPSCmdInfo.txQueue,
+                                       pPloadDesc,
+                                       NWAL_DESC_SIZE);
+
+#else
+            pktio_send(netcp_sb_tx_chan,tip,&meta2,&err);
+#endif
+            continue;
+        }
+        else 
+            //inflow mode.  flip and send
+            flip_and_send_pkt(tip,p_pkt,len,1);
+    }
+    else if ((p_head->ip[2]&0x0000ff00)!=0x00001100)
+    {
+        stats.n_new+=1;Pktlib_freePacket(tip); continue;
+    }
+    else  //non ipsec
+    {
+        if (!check_header(p_head,&meta[i]))
+        {
+            stats.n_bad+=1;Pktlib_freePacket(tip); 
+            continue;
+        }
+
+#if 0
+       /* 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);
+#endif
+             //just flip and send
+            flip_and_send_pkt(tip,p_pkt,len,0);
+        }
+    }
+    //printf("recv done\n");
+}
+
+#ifdef TEST_TIMERS
+//timer callback 
+void our_timer_cb( HPLIB_TIMER_GROUP_HANDLE_T th,
+        int n_fired,     //# timers fired
+        HPLIB_TIMER_LIST_T fired_list,
+        uint64_t currentTime)
+{
+int i;
+HPLIB_TIMER_T tx;
+int cookie;
+int err;
+unsigned long long et;
+//DEBUGprintf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);
+tx = hplib_Timer_GetFirst(fired_list);
+for(i=0;i<n_fired;i++)
+{
+  cookie = (int) hplib_Time_rGetCookie(tx);
+  et =  hplib_Timer_GetTs(tx); //debug
+  //DEBUGprintf("   timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);
+  if (cookie ==1)
+  {  
+     stats.n_t1+=1;
+     t1 = hplib_Timer_Start(
+        th,
+        (void *) 1,
+        100LL,  //timer group tics
+        &err);
+  }
+  else if (cookie ==2)
+  {
+      stats.n_t2+=1;
+      t2 = hplib_Timer_Start(
+        th,
+        (void *) 2,
+        200LL,  //timer group ticks
+        &err);
+  }
+  else
+  {
+    stats.n_t3+=1;
+    t3 = hplib_Timer_Start(
+        th,
+        (void *) 3,
+        300LL,  //timer group ticks
+        &err);
+    //cancel 1 and restart 1
+   hplib_Timer_Cancel(th,t1,&err);
+   t1 = hplib_Timer_Start(
+        th,
+        (void *) 1,
+        100LL,  //timer group ticks
+        &err);
+ }
+  tx = hplib_Timer_GetNext(fired_list,tx); 
+}
+}
+#endif
+void print_ipsec_stats(Sa_IpsecStats_t     *p_saIpsecStats, nwal_saAALG auth, nwal_saEALG cipher)
+{
+#if 0
+    if(retVal != nwal_OK)
+    {
+        System_printf("CORE: %d Error getting IP Sec Stats: Ret Status: %d \n",
+                       retVal);
+        return(nwal_FALSE);
+    }
+    if((p_saIpsecStats->pktEncHi) ||(p_saIpsecStats->pktEncLo))
+    {
+        printf("------------- IPSec TX (Encryption Channel) Stats BEGIN --\n");
+    }
+    else
+    {
+        printf("------------- IPSec RX (Decryption Channel) Stats BEGIN --\n");
+    }
+#endif
+    printf("\nAutentication mode: %d, Encryption Mode: %d\n", auth, cipher);
+    printf("IPSec replayOld:0x%x,replayDup:0x%x,authFail:0x%x \n",
+                   p_saIpsecStats->replayOld,p_saIpsecStats->replayDup,p_saIpsecStats->authFail);
+    printf("IPSec txESN:0x%x,rxESN:0x%x,pktEncHi:0x%x,pktEncLo:0x%x,pktDecHi:0x%x,pktDecLo:0x%x \n",
+                   p_saIpsecStats->txESN,p_saIpsecStats->rxESN,p_saIpsecStats->pktEncHi,
+                   p_saIpsecStats->pktEncLo,p_saIpsecStats->pktDecHi,p_saIpsecStats->pktDecLo);
+}
+
+void print_datamode_stats(Sa_DataModeStats_t     *p_saDataModeStats, nwal_saAALG auth, nwal_saEALG cipher)
+{
+
+    printf("\nAutentication mode: %d, Encryption Mode: %d\n", auth, cipher);
+    printf(" Packets processedHi: 0x%x, Packets processed Lo:0x%x\n",
+            p_saDataModeStats->pktHi, p_saDataModeStats->pktLo);
+}
+
+
+
+
+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;
+Pktlib_HeapStats    pktLibHeapStats;
+int i;
+unsigned long long bcpp;
+unsigned long long bcpp_noc;
+unsigned long long bcpp_app;
+unsigned long long bcpp_tx;
+unsigned long long npL;
+unsigned long long cyclesL;
+unsigned long long ccyclesL; //cache cycles
+NETAPI_SA_STATS_T netapi_sa_stats;
+
+printf(">*****stats @ %lld\n", hplib_mUtil_GetTimestamp());
+//printf("netcp_tx_handle check %x\n", netcp_tx_chan->back);
+printf(">itx=%d rx=%d tx=%d bad=%d slow=%d \n>rx_class0=%d rx_class1=%d rx_class2=%d  secRx=%d  secPRX=%d sb_rx=%d sb_tx=%d auth_ok=%d sec_tx=%d\n",
+         stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new, 
+         stats.n_class0_rx, stats.n_class1_rx, 
+         stats.n_class2_rx, stats.sec_rx, stats.secp_rx, stats.sb_rx, stats.sb_tx, stats.n_auth_ok,
+         stats.sec_tx);
+
+if (stats.rx && stats.tx)
+    printf("decrypt time per packet(avg): %lu, encrypt  time per packet(avg): %lu\n", 
+    (unsigned long) stats.total_decrypt_time/stats.rx, (unsigned long) stats.total_encrypt_time/stats.tx);
+netapi_sched_get_stats(&npL,&cyclesL,&ccyclesL);
+if (npL && stats.rx) {
+   bcpp = cyclesL/npL; 
+   bcpp_noc = (cyclesL-ccyclesL)/npL; 
+   bcpp_app = (stats.app_cycles-stats.tx_cache_cycles)/stats.rx;
+} 
+else {bcpp = bcpp_noc=bcpp_app=0L;}
+if (stats.tx)
+{
+    bcpp_tx = (stats.send_cycles-stats.tx_cache_cycles)/stats.tx;
+}else {bcpp_tx = 0L;}
+printf(">         ++ busy cycles pp=%lld (%lld wo cache ops) (app+tx= %lld) (tx= %lld) ++\n",
+         bcpp,bcpp_noc,bcpp_app, bcpp_tx);
+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 IPv6 packets:        %d\n", pPaStats->classify1.nIpv6Packets);
+       printf("C1 number Custom packets:        %d\n", pPaStats->classify1.nCustomPackets);
+       printf("C1 number SRIO packets:        %d\n", pPaStats->classify1.nSrioPackets);
+       printf("C1 number LLC/SNAP Fail packets:        %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 IP Fragmented packets: %d\n", pPaStats->classify1.nIpFrag);
+       printf("C1 number IP Depth Overflow: %d\n", pPaStats->classify1.nIpDepthOverflow);
+       printf("C1 number VLAN Depth Overflow: %d\n", pPaStats->classify1.nVlanDepthOverflow);
+       printf("C1 number GRE Depth Overflow: %d\n", pPaStats->classify1.nGreDepthOverflow);
+       printf("C1 number MPLS Packets: %d\n", pPaStats->classify1.nMplsPackets);
+       printf ("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);
+       printf("C1 number of Invalid IPv6 Opt:  %d\n", pPaStats->classify1.nInvalidIPv6Opt);
+       printf("C1 number of TX IP Fragments:  %d\n", pPaStats->classify1.nTxIpFrag);
+       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 Packets  :           %d\n",pPaStats->classify2.nPackets);
+       printf ("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);
+       printf ("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);
+       printf ("C2 number Custom       :      %d\n",pPaStats->classify2.nCustom);
+       printf ("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);
+       printf ("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);
+       printf ("C2 number Modify Stats Cmd Fail :      %d\n\n",pPaStats->modify.nCommandFail);
+}
+Pktlib_getHeapStats(OurHeap, &pktLibHeapStats);
+printf("main heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
+                                pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
+printf("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
+                        pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
+                        pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
+
+Pktlib_getHeapStats(specialSmall, &pktLibHeapStats);
+printf("specialSmall heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
+                                pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
+printf("                       >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
+                                pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
+                                pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
+
+
+Pktlib_getHeapStats(specialLarge, &pktLibHeapStats);
+printf("specialLarge heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
+                                pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
+printf("                       >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
+                                pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
+                                pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
+
+
+#if 0
+printf("pa2sa descriptor area dump\n");
+for(i=0;i<TUNE_NETAPI_CONFIG_MAX_PA_TO_SA_DESC;i++)
+{
+   extern long * pa2sa_descr_base;
+   long * tip= &pa2sa_descr_base[32*i]; 
+   dump_descr(tip, i);
+}
+printf("sa2pa descriptor area dump\n");
+for(i=0;i<TUNE_NETAPI_CONFIG_MAX_SA_TO_PA_DESC;i++)
+{
+   extern long * sa2pa_descr_base;
+   long * tip= &sa2pa_descr_base[32*i]; 
+   dump_descr(tip, i);
+}
+#endif
+#ifdef TEST_TIMERS
+//debug = dump timer polling stats
+dump_poll_stats();
+//debug = dump timer polling stats
+//dump_poll_stats();
+#endif
+#ifndef EXPERIMENTAL
+    for (i = 0; i < MAX_SEC_INDEX; i++)
+#else
+    for (i=0; i < 1;i++)
+#endif
+    {
+        /* Statistics for RX Tunnel */
+        memset(&netapi_sa_stats, 0, sizeof(netapi_sa_stats));
+        netapi_getSaStats(netapi_handle, sa_info[i].rx_tunnel, &netapi_sa_stats);
+        if (netapi_sa_stats.validParams & NETAPI_IPSEC_STAT_VALID)
+        {
+             print_ipsec_stats(&(netapi_sa_stats.saIpsecStats), 
+                                 rx_sa[i].authMode, 
+                                 rx_sa[i].cipherMode);
+        }
+        if (netapi_sa_stats.validParams & NETAPI_SIDEBAND_DATA_MODE_STAT_VALID)
+        {
+            print_datamode_stats(&(netapi_sa_stats.dataModeStats),
+                                   rx_sa[i].authMode, 
+                                   rx_sa[i].cipherMode);
+        }
+        
+        /* Statistics for TX Tunnel */
+        memset(&netapi_sa_stats, 0, sizeof(netapi_sa_stats));
+        netapi_getSaStats(netapi_handle, sa_info[i].tx_tunnel, &netapi_sa_stats);
+        if (netapi_sa_stats.validParams & NETAPI_IPSEC_STAT_VALID)
+        {
+             print_ipsec_stats(&(netapi_sa_stats.saIpsecStats), 
+                                 tx_sa[i].authMode, 
+                                 tx_sa[i].cipherMode);
+        }
+        if (netapi_sa_stats.validParams & NETAPI_SIDEBAND_DATA_MODE_STAT_VALID)
+        {
+            print_datamode_stats(&(netapi_sa_stats.dataModeStats),
+                                   tx_sa[i].authMode, 
+                                   tx_sa[i].cipherMode);
+        }
+    }
+    netapi_dump_internal_heap_stats();
+}
+
+//******************************************************
+//use scheduling housekeeping callback to generate pkts
+//******************************************************
+static int done_burst=0;
+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},0};
+int err;
+static int house_pkts_gened=0;
+int p;
+unsigned char * pIpHdr,* pData;
+unsigned int vv1,vv2,vv3;
+unsigned int sum_vv1=0;
+unsigned int sum_vv2=0;
+unsigned int sum_vv3=0;
+unsigned int sum_vv4=0;
+unsigned int sum_vv5=0;
+
+unsigned int nwal_flow_vv1,nwal_flow_vv2;
+unsigned int nwal_sum_vv1=0;
+unsigned int nwal_sum_vv2=0;
+unsigned int nwal_sum_vv3=0;
+unsigned int nwal_sum_vv4=0;
+unsigned int nwal_sum_vv5=0;
+unsigned int nwal_sum_vv6=0;
+
+unsigned int nwal_sum_flow_vv1=0;
+unsigned int nwal_sum_flow_vv2=0;
+unsigned int cache_op_b1;
+unsigned int cache_op_b2;
+int n_c_ops;
+static int first =0;
+Cppi_HostDesc*      pPktDesc;
+
+if(done_burst)
+{
+  house_pkts_gened+=TX_BURST;
+  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)
+  {
+     netapi_schedShutdown(s,NULL,&err);
+  }
+  return;
+}
+done_burst=1;
+Osal_cache_op_measure_reset();
+memset(&meta_tx,0,sizeof(meta_tx));
+for(p=0;p<TX_BURST;p++) {  
+//reguest stats 
+if ((house_pkts_gened>0) && (! (house_pkts_gened%1000)) )
+{
+   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, OurHeap, PKT_LEN,&testPkt[0]  , TEST_PKT_LEN);
+   if(!tip) { house_pkts_gened +=1; continue; }
+
+
+   /* set the pkt length */
+   vv1 = hplib_mUtil_GetTickCount();
+   Pktlib_setPacketLen(tip, len);
+
+   /* set up meta data */
+    meta.sa_handle=nwal_HANDLE_INVALID;
+//#define BENCH_UDP_SEND
+#ifdef BEND_UDP_SEND
+    meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID);
+    meta_tx.startOffset = 0;
+    //GONE in V2 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;
+    //GONE in V2 meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;
+    meta_tx.ploadLen = TEST_PAYLOAD_LEN;
+
+    Pktlib_getDataBuffer(tip,&pData,&len);
+   if(house_pkts_gened &0x1)
+   {
+        memcpy(&pData[6],&config.mac1[0] ,6);
+   }
+    pIpHdr = pData + meta_tx.ipOffBytes;
+    meta_tx.pseudoHdrChecksum =
+        test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));
+#else
+   Pktlib_getDataBuffer(tip,&pData,&len);
+   if(house_pkts_gened &0x1)
+   {
+        memcpy(&pData[6],&config.mac1[0] ,6);
+   }
+    meta_tx.txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID;
+    meta_tx.startOffset = 0;
+    meta_tx.ploadLen = TEST_PAYLOAD_LEN;
+#endif
+   /* 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
+
+   if(!first)
+   {
+       first++;
+       nwal_flow_vv1= hplib_mUtil_GetTickCount();
+       if(nwal_initPSCmdInfo(PKTIO_GET_NWAL_INSTANCE(netcp_tx_chan),
+                             &meta_tx,
+                             &flowPSCmdInfo) != nwal_OK)
+       {
+           printf("nwal_initPSCmdInfo() ERROR \n");
+       }
+       nwal_flow_vv2= hplib_mUtil_GetTickCount();
+       nwal_sum_flow_vv1 += (nwal_flow_vv1-vv1); 
+       nwal_sum_flow_vv2 += (nwal_flow_vv2-nwal_flow_vv1); 
+   }
+       
+   cache_op_b1= Osal_cache_op_measure(&n_c_ops);
+   vv2= hplib_mUtil_GetTickCount();
+#ifdef BEND_UDP_SEND
+   nwal_mCmdSetL4CkSumPort(  tip,
+                             &flowPSCmdInfo,
+                             TEST_PKT_UDP_OFFSET_BYTES,
+                             (TEST_PKT_UDP_HDR_LEN + TEST_PAYLOAD_LEN),
+                             meta_tx.pseudoHdrChecksum,
+                             meta_tx.enetPort);
+#else
+   nwal_mCmdSetPort  (tip,
+                      &flowPSCmdInfo,  //could be NULL
+                      0);  //port 0 -> switch decides
+
+#endif
+
+   pPktDesc = Pktlib_getDescFromPacket(tip);
+   /* Send the packet out to transmit Q*/
+   Qmss_queuePushDescSize (flowPSCmdInfo.txQueue, 
+                        pPktDesc, 
+                        NWAL_DESC_SIZE);
+   vv3= hplib_mUtil_GetTickCount();
+   cache_op_b2= Osal_cache_op_measure(&n_c_ops);
+
+   sum_vv1 += (vv2-vv1);
+   if(!house_pkts_gened)
+   {
+       /* first packet. Take out the PS command label creation cost */
+       sum_vv1 = sum_vv1 - nwal_sum_flow_vv2;
+   }
+
+   sum_vv3 += (vv3-vv2)-(cache_op_b2-cache_op_b1); //sub out cache op cost
+
+   // printf("pktio send. full=%d metadata=%d pktio_send=%d\n", vv3-vv1,  vv2-vv1,  vv3-vv2);
+   
+
+   stats.itx +=1;
+   house_pkts_gened +=1;
+ }
+{
+   unsigned int ccycles;
+   ccycles =Osal_cache_op_measure(&n_c_ops);
+   if (sum_vv1) 
+   {
+      printf("BURST NWAL Fast send %d pkts.  metadata=%d Cmd Label Creation Cost=%d  nwal Fast Send Cost (less cacheop)= %d n_c_ops=%d cache_op_time=%d (pp-> %d)\n", 
+              stats.itx, sum_vv1/stats.itx,  nwal_sum_flow_vv2, sum_vv3/stats.itx, 
+              n_c_ops, ccycles, n_c_ops? (ccycles/(n_c_ops/2)) : 0);
+#if 0
+      printf("NWAL Profile Cycles: Prof1= %d,Prof2=%d,Prof3=%d,Prof4=%d,Prof5=%d ,Prof6=%d \n",
+              nwal_sum_vv1/stats.itx,nwal_sum_vv2/stats.itx,nwal_sum_vv3/stats.itx,
+              nwal_sum_vv4/stats.itx,nwal_sum_vv5/stats.itx,nwal_sum_vv6/stats.itx);
+  
+#endif  
+
+      if(stats.itx2)
+      {
+          printf("nwal_flowSend Profile Cycles: Prof1= %d,Prof2=%d \n",
+              nwal_sum_flow_vv1/stats.itx2,nwal_sum_flow_vv2/stats.itx2);
+      }
+
+   }
+}
+}
+
+void  build_sa_db(int i)
+{
+    long tmp_spi;
+    if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_SHA1) && (tx_sa[i].cipherMode == NWAL_SA_EALG_AES_CBC))
+    {
+        /* static configuration, will not change */
+        sa_info[i].tx_payload_info.aadSize = 0;
+        sa_info[i].tx_payload_info.pAad = NULL;
+        sa_info[i].tx_payload_info.pAuthIV = NULL;
+        sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;        /*done: same for all cipher suites */         
+        sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN +
+                                                                     netTest_IP_HEADER_LEN +
+                                                                    netTest_ESP_HEADER_LEN +
+                                                                    netTest_AES_CBC_IV_LEN;
+
+        /* dynamic configuration, will  be calculated on the fly */
+        sa_info[i].tx_payload_info.authSize = 0; /* pkt len - mac - ip -icv (12) */
+        sa_info[i].tx_payload_info.encSize = 0;   /* authSize - esp header size (always 8 bytes) */
+        sa_info[i].tx_payload_info.pEncIV = 0;
+        sa_info[i].tx_payload_info.pPkt = 0;     /* not being referenced in net_test */
+
+        sa_info[i].cipherMode = NWAL_SA_EALG_AES_CBC;
+        sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].auth_tag_size = netTest_ICV_LEN;  /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
+#ifdef EXPERIMENTAL
+        sa_info[i].iv_len=16;
+        sa_info[i].bl=16;
+        sa_info[i].spi = tx_sa[i].spi;
+        sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
+        sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
+#endif
+        sa_info[i].tx_pkt_info.enetPort = 0;
+        sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
+        sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.startOffset = 0;
+        sa_info[i].tx_pkt_info.lpbackPass = 0;
+        sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
+        sa_info[i].tx_pkt_info.pPkt = NULL;
+        sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.saPayloadLen = 0;
+        sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
+       
+        sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
+
+        tmp_spi = htonl((long)(tx_sa[i].spi));
+         trie_insert(p_trie_sa,(char *)&tmp_spi,4, (void *) &sa_info[i]); //asociate with tx sa SPI
+         printf("*********** build_sa_db(): spi %d,0x%x\n", tx_sa[i].spi,tx_sa[i].spi);;
+         
+         
+    }
+    else if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_SHA2_256) && (tx_sa[i].cipherMode == NWAL_SA_EALG_AES_CTR))
+    {
+        printf("inside build_sa_db, index %d\n", i);
+        /* static configuration, will not change */
+        sa_info[i].tx_payload_info.aadSize = 0;
+        sa_info[i].tx_payload_info.pAad = NULL;
+        sa_info[i].tx_payload_info.pAuthIV = NULL;
+        sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;        /*done: same for all cipher suites */
+        sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN +
+                                                                     netTest_IP_HEADER_LEN +
+                                                                    netTest_ESP_HEADER_LEN +
+                                                                    netTest_AES_CTR_IV_LEN;
+
+
+
+
+        /* dynamic configuration, will  be calculated on the fly */
+        sa_info[i].tx_payload_info.authSize = 0;
+        sa_info[i].tx_payload_info.encSize = 0;
+        sa_info[i].tx_payload_info.pEncIV = 0;
+        sa_info[i].tx_payload_info.pPkt = 0;
+
+        sa_info[i].cipherMode = NWAL_SA_EALG_AES_CTR;
+        sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].auth_tag_size = netTest_ICV_LEN;  /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
+#ifdef EXPERIMENTAL
+        sa_info[i].iv_len=8;
+        sa_info[i].bl=8;
+        sa_info[i].spi = tx_sa[i].spi;
+        sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
+        sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
+#endif
+
+        sa_info[i].tx_pkt_info.enetPort = 0;
+        sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
+        sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.startOffset = 0;
+        sa_info[i].tx_pkt_info.lpbackPass = 0;
+        sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
+        sa_info[i].tx_pkt_info.pPkt = NULL;
+        sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.saPayloadLen = 0;
+        sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
+       
+        sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
+
+        tmp_spi = htonl((long)(tx_sa[i].spi));
+         trie_insert(p_trie_sa,(char *)&tmp_spi,4, (void *) &sa_info[i]); //asociate with tx sa SPI
+    }
+    else if ((tx_sa[i].authMode == NWAL_SA_AALG_NULL) && (tx_sa[i].cipherMode == NWAL_SA_EALG_3DES_CBC))
+    {
+        /* static configuration, will not change */
+        sa_info[i].tx_payload_info.aadSize = 0;
+        sa_info[i].tx_payload_info.pAad = NULL;
+        sa_info[i].tx_payload_info.pAuthIV = NULL;
+        sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;        /*done: same for all cipher suites */
+        sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN +
+                                                                     netTest_IP_HEADER_LEN +
+                                                                    netTest_ESP_HEADER_LEN +
+                                                                    netTest_3DES_CBC_IV_LEN;
+
+        /* dynamic configuration, will  be calculated on the fly */
+        sa_info[i].tx_payload_info.authSize = 0;
+        sa_info[i].tx_payload_info.encSize = 0;
+        sa_info[i].tx_payload_info.pEncIV = 0;
+        sa_info[i].tx_payload_info.pPkt = 0;
+
+        sa_info[i].cipherMode = NWAL_SA_EALG_3DES_CBC;
+        sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].auth_tag_size = 0;  /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
+#ifdef EXPERIMENTAL
+        sa_info[i].iv_len=8;
+        sa_info[i].bl=8;
+        sa_info[i].spi = tx_sa[i].spi;
+        sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
+        sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
+#endif
+
+        sa_info[i].tx_pkt_info.enetPort = 0;
+        sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
+        sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.startOffset = 0;
+        sa_info[i].tx_pkt_info.lpbackPass = 0;
+        sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
+        sa_info[i].tx_pkt_info.pPkt = NULL;
+        sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.saPayloadLen = 0;
+        sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
+       
+        sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
+
+        tmp_spi = htonl((long)(tx_sa[i].spi));
+         trie_insert(p_trie_sa,(char *)&tmp_spi,4, (void *) &sa_info[i]); //asociate with tx sa SPI
+    }
+    else if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_MD5) && (rx_sa[i].cipherMode == NWAL_SA_EALG_NULL))
+    {
+        /* static configuration, will not change */
+        sa_info[i].tx_payload_info.aadSize = 0;
+        sa_info[i].tx_payload_info.pAad = NULL;
+        sa_info[i].tx_payload_info.pAuthIV = NULL;
+        sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;        /*done: same for all cipher suites */
+
+        sa_info[i].tx_payload_info.encOffset =         netTest_MAC_HEADER_LEN +
+                                                                     netTest_IP_HEADER_LEN +
+                                                                    netTest_ESP_HEADER_LEN +
+                                                                    netTest_NULL_IV_LEN;
+
+        
+#ifdef EXPERIMENTAL
+        sa_info[i].iv_len=0;
+        sa_info[i].bl=4;
+        sa_info[i].spi = tx_sa[i].spi;
+        sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
+        sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
+#endif
+
+
+        /* dynamic configuration, will  be calculated on the fly */
+        sa_info[i].tx_payload_info.authSize = 0;
+        sa_info[i].tx_payload_info.encSize = 0;
+        sa_info[i].tx_payload_info.pEncIV = 0;
+        sa_info[i].tx_payload_info.pPkt = 0;
+
+        sa_info[i].cipherMode = NWAL_SA_EALG_NULL;
+        sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].auth_tag_size = netTest_ICV_LEN;  /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
+
+        sa_info[i].tx_pkt_info.enetPort = 0;
+        sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
+        sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.startOffset = 0;
+        sa_info[i].tx_pkt_info.lpbackPass = 0;
+        sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
+        sa_info[i].tx_pkt_info.pPkt = NULL;
+        sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.saPayloadLen = 0;
+        sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
+       
+        sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
+        tmp_spi = htonl((long)(tx_sa[i].spi));
+         trie_insert(p_trie_sa,(char *)&tmp_spi,4, (void *) &sa_info[i]); //asociate with tx sa SPI
+    }
+    else if ((tx_sa[i].authMode == NWAL_SA_AALG_NULL) && (rx_sa[i].cipherMode == NWAL_SA_EALG_AES_GCM))
+    {
+        /* static configuration, will not change */
+        sa_info[i].tx_payload_info.aadSize = 0;
+        sa_info[i].tx_payload_info.pAad = NULL;
+        sa_info[i].tx_payload_info.pAuthIV = NULL;
+        sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;        /*done: same for all cipher suites */
+        //sa_info[i].tx_payload_info.encIvSize = netTest_AES_GCM_IV_LEN;
+
+        sa_info[i].tx_payload_info.encOffset =         netTest_MAC_HEADER_LEN +
+                                                                     netTest_IP_HEADER_LEN +
+                                                                    netTest_ESP_HEADER_LEN +
+                                                                    netTest_AES_GCM_IV_LEN;
+#ifdef EXPERIMENTAL
+        sa_info[i].iv_len=0;
+        sa_info[i].bl=4;
+        sa_info[i].spi = tx_sa[i].spi;
+        sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
+        sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
+#endif
+
+
+        /* dynamic configuration, will  be calculated on the fly */
+        sa_info[i].tx_payload_info.authSize = 0;
+        sa_info[i].tx_payload_info.encSize = 0;
+        //sa_info[i].tx_payload_info.ploadLen = 0;
+        sa_info[i].tx_payload_info.pEncIV = 0;
+        sa_info[i].tx_payload_info.pPkt = 0;
+
+        sa_info[i].cipherMode = NWAL_SA_EALG_AES_GCM;
+        sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].auth_tag_size = netTest_AES_GCM_CCM_ICV_LEN;  /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
+
+        sa_info[i].tx_pkt_info.enetPort = 0;
+        sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
+        sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.startOffset = 0;
+        sa_info[i].tx_pkt_info.lpbackPass = 0;
+        sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
+        sa_info[i].tx_pkt_info.pPkt = NULL;
+        sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.saPayloadLen = 0;
+        sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
+       
+        sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
+
+        tmp_spi = htonl((long)(tx_sa[i].spi));
+         trie_insert(p_trie_sa,(char *)&tmp_spi,4, (void *) &sa_info[i]); //asociate with tx sa SPI
+    }
+    else if ((tx_sa[i].authMode == NWAL_SA_AALG_NULL) && (rx_sa[i].cipherMode == NWAL_SA_EALG_AES_CCM))
+    {
+        /* static configuration, will not change */
+        sa_info[i].tx_payload_info.aadSize = 0;
+        sa_info[i].tx_payload_info.pAad = NULL;
+        //sa_info[i].tx_payload_info.authIvSize = 0;
+        sa_info[i].tx_payload_info.pAuthIV = NULL;
+        sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;        /*done: same for all cipher suites */
+
+        sa_info[i].tx_payload_info.encOffset =         netTest_MAC_HEADER_LEN +
+                                                                     netTest_IP_HEADER_LEN +
+                                                                    netTest_ESP_HEADER_LEN +
+                                                                    netTest_AES_CCM_IV_LEN;
+#ifdef EXPERIMENTAL
+        sa_info[i].iv_len=0;
+        sa_info[i].bl=4;
+        sa_info[i].spi = tx_sa[i].spi;
+        sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
+        sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
+#endif
+
+
+        /* dynamic configuration, will  be calculated on the fly */
+        sa_info[i].tx_payload_info.authSize = 0;
+        sa_info[i].tx_payload_info.encSize = 0;
+        //sa_info[i].tx_payload_info.ploadLen = 0;
+        sa_info[i].tx_payload_info.pEncIV = 0;
+        sa_info[i].tx_payload_info.pPkt = 0;
+
+        sa_info[i].cipherMode = NWAL_SA_EALG_AES_CCM;
+        sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].auth_tag_size = netTest_AES_GCM_CCM_ICV_LEN;  /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
+
+        sa_info[i].tx_pkt_info.enetPort = 0;
+        sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
+        sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.startOffset = 0;
+        sa_info[i].tx_pkt_info.lpbackPass = 0;
+        sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
+        sa_info[i].tx_pkt_info.pPkt = NULL;
+        sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.saPayloadLen = 0;
+        sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
+       
+        sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
+
+        tmp_spi = htonl((long)(tx_sa[i].spi));
+         trie_insert(p_trie_sa,(char *)&tmp_spi,4, (void *) &sa_info[i]); //asociate with tx sa SPI
+    }
+    else if ((tx_sa[i].authMode == NWAL_SA_AALG_GMAC) && (rx_sa[i].cipherMode == NWAL_SA_EALG_NULL))
+    {
+        /* static configuration, will not change */
+        sa_info[i].tx_payload_info.aadSize = 0;
+        sa_info[i].tx_payload_info.pAad = NULL;
+        sa_info[i].tx_payload_info.pAuthIV = NULL;
+        sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;
+
+
+        sa_info[i].tx_payload_info.encOffset =         netTest_MAC_HEADER_LEN +
+                                                                     netTest_IP_HEADER_LEN +
+                                                                    netTest_ESP_HEADER_LEN +
+                                                                    netTest_AES_GMAC_IV_LEN;
+#ifdef EXPERIMENTAL
+        sa_info[i].iv_len=0;
+        sa_info[i].bl=4;
+        sa_info[i].spi = tx_sa[i].spi;
+        sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
+        sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
+#endif
+
+
+        /* dynamic configuration, will  be calculated on the fly */
+        sa_info[i].tx_payload_info.authSize = 0;
+        sa_info[i].tx_payload_info.encSize = 0;
+        //sa_info[i].tx_payload_info.ploadLen = 0;
+        sa_info[i].tx_payload_info.pEncIV = 0;
+        sa_info[i].tx_payload_info.pPkt = 0;
+
+        sa_info[i].cipherMode = NWAL_SA_EALG_NULL;
+        sa_info[i].authMode = NWAL_SA_AALG_GMAC;
+        sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].auth_tag_size = netTest_AES_GMAC_ICV_LEN;  /* icv or mac size,. always 12 except for AES_CCM/AES_GCM , GMAC*/
+
+        sa_info[i].tx_pkt_info.enetPort = 0;
+        sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
+        sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
+        sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.startOffset = 0;
+        sa_info[i].tx_pkt_info.lpbackPass = 0;
+        sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
+        sa_info[i].tx_pkt_info.pPkt = NULL;
+        sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;
+        sa_info[i].tx_pkt_info.saPayloadLen = 0;
+        sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
+       
+        sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
+
+        tmp_spi = htonl((long)(tx_sa[i].spi));
+         trie_insert(p_trie_sa,(char *)&tmp_spi,4, (void *) &sa_info[i]); //asociate with tx sa SPI
+    }
+    else
+        printf("build_sa_db(): invalid encryption/authentication combination selected\n");
+
+    //printf("sa_build_db(): authOffset %d, innerIpOffset %d, encOffset %d\n", sa_info[i].tx_payload_info.authOffset, sa_info[i].inner_ip_offset, sa_info[i].tx_payload_info.encOffset);
+    
+    
+}
+
+
+
+#define CHECK_SET_PARAM(ARG1, ARG2)     \
+    do { \
+        if(strcmp(key, ARG1) == 0) { \
+        if(data)strncpy(ARG2,data,CONFIG_STRING_LEN); \
+        printf("CHECK_SET_PARM, match found, input cong string %s\n", ARG2); \
+        continue; \
+        } \
+    } while(0)
+
+#define CHECK_SET_PARAM2(ARG1, ARG2,  ARG3)     \
+    do { \
+        if(strcmp(key, ARG1) == 0) { \
+        if(data) strncpy(ARG2,data,CONFIG_STRING_LEN); \
+        if(data2) strncpy(ARG3,data2,CONFIG_STRING_LEN); \
+        printf("CHECK_SET_PARM2, match found, input cong string %s %s\n", ARG2, ARG3); \
+        continue; \
+        } \
+    } while(0)
+
+unsigned char hex2dec(char *p_s)
+{
+  int val;
+  sscanf(p_s,"%x",&val); 
+ return val&0xff;
+}
+void parse_one_mac(char * p_mac_str, unsigned char *p_mac)
+{
+    int index = 0;
+    int i;
+    char *pch = strtok (&(p_mac_str[0]),"-");
+
+    while (pch != NULL)
+    {
+         printf ("%s\n",pch);
+         p_mac[index] = hex2dec(pch);
+         index++;
+         pch = strtok (NULL,"-");
+    }
+     printf("index value : %d\n", index);
+    for (i=0; i<6;i++)
+         printf("************mac0[%d]: 0x%x\n",i,  p_mac[i]);
+}
+
+void parse_one_ip(char * p_ip_addr_str, unsigned char * p_ip)
+{
+    int index = 0;
+    int i;
+    char * pch = strtok (&p_ip_addr_str[0],".");
+
+     while (pch != NULL)
+     {
+        printf ("xxxxx: %s\n",pch);
+        p_ip[index] = atoi(pch);
+        index++;
+        pch = strtok (NULL,".");
+    }
+    printf("index value : %d\n", index);
+    for (i=0; i<4;i++)
+        printf("************ip[%d]: 0x%x\n",i, p_ip[i]);
+
+
+}
+
+void parse_mac_address(netTestConfigFile_t *pConfig)
+{
+    if (strlen(&pConfig->mac0[0]))
+        parse_one_mac(&pConfig->mac0[0],&config.mac0[0]);
+    if (strlen(&pConfig->mac1[0]))
+        parse_one_mac(&pConfig->mac1[0],&config.mac1[0]);
+}
+void parse_ip_address(netTestConfigFile_t *pConfig)
+{
+    if (strlen(&pConfig->ip0[0]))
+        parse_one_ip(&pConfig->ip0[0],&config.ip0.ipv4[0]);
+    if (strlen(&pConfig->ip1[0]))
+        parse_one_ip(&pConfig->ip1[0],&config.ip1.ipv4[0]);
+    if (strlen(&pConfig->ip2[0]))
+        parse_one_ip(&pConfig->ip2[0],&config.ip2.ipv4[0]);
+    if (strlen(&pConfig->local_ipsec_ip[0]))
+        parse_one_ip(&pConfig->local_ipsec_ip[0],&config.local_ipsec_ip.ipv4[0]);
+    if (strlen(&pConfig->remote_ipsec_ip[0]))
+    parse_one_ip(&pConfig->remote_ipsec_ip[0],&config.remote_ipsec_ip.ipv4[0]);
+}
+
+
+void parse_ipsec_mode(netTestConfigFile_t *pConfig)
+{
+
+    if (strlen(&pConfig->ipsec_mode_rx[0]))
+    {
+        if (strcmp(pConfig->ipsec_mode_rx, "SIDEBAND") == 0)
+        {
+            config.ipsec_mode_rx = IPSEC_MODE_RX_SIDEBAND;
+        }
+        else if (strcmp(pConfig->ipsec_mode_rx, "INFLOW") == 0)
+        {
+            config.ipsec_mode_rx = IPSEC_MODE_RX_INFLOW;
+        }
+        else
+            printf("parse_ipsec_mode(), invalid RX ipsec mode in config file \n");
+    }
+
+    if (strlen(&pConfig->ipsec_mode_tx[0]))
+    {
+        if (strcmp(pConfig->ipsec_mode_tx, "SIDEBAND") == 0)
+        {
+            config.ipsec_mode_tx = IPSEC_MODE_TX_SIDEBAND;
+        }
+        else if (strcmp(pConfig->ipsec_mode_tx, "INFLOW") == 0)
+        {
+            config.ipsec_mode_tx = IPSEC_MODE_TX_INFLOW;
+        }
+    else
+        printf("parse_ipsec_mode(), invalid TX ipsec mode in config file \n");
+    }
+
+    printf("parse_ipsec_mode(): RX mode %d\n", config.ipsec_mode_rx);
+    printf("parse_ipsec_mode(): TX mode %d\n", config.ipsec_mode_tx);
+
+    
+}
+
+#ifdef EXPERIMENTAL
+int n_routes=0;
+int n_dst_ips=0;
+void parse_routes(netTestConfigFile_t *pConfig)
+{
+int i;
+int said=0;
+for(i=0;i<MAX_ROUTES;i++)
+{
+   int port;
+   if (pConfig->routes[i][0])
+   {
+      port=atoi(&pConfig->ports[i][0]);
+      if((port<1)||(port>2)) continue; //bad port #: only 1 or 2 valid
+      if(strncmp(&pConfig->routes[i][0],"MAC",3)==0)
+      {
+         routes[i].out_port = port;
+         parse_one_mac(&pConfig->routes[i][3],&routes[i].out_mac[0]);
+         memcpy(&routes[i].out_mac[6], ((port==1) ?&config.mac0[0]: &config.mac1[0] ),6); 
+         routes[i].out_mac[12]=0x08;
+         routes[i].out_mac[13]=0x00;
+         routes[i].sec_ptr=NULL;
+         n_routes+=1;
+      }
+      else if (strncmp(&pConfig->routes[i][0],"SA",2)==0)
+      {      
+         said=atoi(&pConfig->routes[i][2]) ;
+         routes[i].sec_ptr=&sa_info[said];
+         n_routes+=1;
+      }
+   }
+}
+our_router = route_init();
+for (i=0;i<MAX_ROUTES;i++)
+{
+  unsigned long ip_be;
+  int route_index;
+  if (pConfig->dst_ips[i][0])
+  {
+     parse_one_ip(&pConfig->dst_ips[i][0],(unsigned char *)&ip_be);
+     sscanf(&pConfig->paths[i][0],"route%d",&route_index);
+     route_add(our_router,&ip_be,&routes[route_index]);
+     n_dst_ips+=1;
+  }
+}
+printf(">Route DB built.  %d entries\n",n_dst_ips);
+}
+#endif
+static void parse_config_file(FILE * fpr, netTestConfigFile_t *pConfig)
+{
+    char line[MAX_LINE_LENGTH + 1];
+    int i;
+    char *key, *data, *ep, *data2;
+    char tokens[] = " :=;\n";
+    char temp_str[50];
+    memset(line, 0, MAX_LINE_LENGTH + 1);
+    memset(pConfig, 0, sizeof(netTestConfigFile_t));
+    while (fgets(line, MAX_LINE_LENGTH + 1, fpr)) 
+    {
+        if(line[0]=='#') continue; //skip comment
+        key  = (char *)strtok(line, tokens);
+        data = (char *)strtok(NULL, tokens);
+        data2 = (char *)strtok(NULL, tokens);
+        if (!key) continue;
+        if (!data) continue;
+
+        if(strlen(data) == 0) 
+        {
+            continue;
+        }
+
+         CHECK_SET_PARAM(INIT_CONFIG_MAC0,&(pConfig->mac0[0]));
+         CHECK_SET_PARAM(INIT_CONFIG_MAC1,&(pConfig->mac1[0]));
+         CHECK_SET_PARAM(INIT_CONFIG_IP0,&(pConfig->ip0[0]));
+         CHECK_SET_PARAM(INIT_CONFIG_IP1,&(pConfig->ip1[0]));
+         CHECK_SET_PARAM(INIT_CONFIG_IP2,&(pConfig->ip2[0]));
+         CHECK_SET_PARAM(INIT_CONFIG_LOCAL_IPSEC_IP,&(pConfig->local_ipsec_ip[0]));
+         CHECK_SET_PARAM(INIT_CONFIG_REMOTE_IPSEC_IP,&(pConfig->remote_ipsec_ip[0]));
+         CHECK_SET_PARAM(INIT_CONFIG_IPSEC_MODE_RX,&(pConfig->ipsec_mode_rx[0]));
+         CHECK_SET_PARAM(INIT_CONFIG_IPSEC_MODE_TX,&(pConfig->ipsec_mode_tx[0]));
+         CHECK_SET_PARAM(INIT_CONFIG_IPSEC_IF_NO,&(pConfig->ipsec_if_no[0]));
+#ifdef EXPERIMENTAL
+    for(i=0;i<MAX_ROUTES;i++)
+    {
+        sprintf(temp_str,"route%d",i);
+        CHECK_SET_PARAM2(temp_str,&pConfig->routes[i][0],&pConfig->ports[i][0] );
+    }
+    for(i=0;i<MAX_ROUTES;i++)
+    {
+        sprintf(temp_str,"dstip%d",i);
+        CHECK_SET_PARAM2(temp_str,&pConfig->dst_ips[i][0],&pConfig->paths[i][0] );
+    }
+#endif
+         
+    }
+    parse_mac_address(pConfig);
+
+    parse_ip_address(pConfig);
+
+    parse_ipsec_mode(pConfig);
+#ifdef EXPERIMENTAL
+     if (strlen(&pConfig->ipsec_if_no[0]))
+        config.ipsec_if_no = atoi(&pConfig->ipsec_if_no[0]);
+    parse_routes(pConfig);
+#endif
+}
+
+static  netTestConfigFile_t config_file;
+/***************************************
+ ********** test driver*****************
+ ***************************************/
+int main(int argc, char **argv)
+{
+    int err,i;
+    rlim_t oss,ss = 1024*1024;
+    struct rlimit rl;
+
+    Pktlib_HeapCfg      heapCfg;
+    int32_t             errCode;
+    Pktlib_HeapIfTable*  pPktifTable;
+    FILE * fpr = NULL;
+
+
+
+    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);
+i   f (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");
+#endif
+
+
+    if (argc>=2)  np2process = atoi(argv[1]);
+        printf("*************** np2process %d\n", np2process);
+    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);}
+#if 1
+
+#if 0
+    if (argc >= 2) 
+    {
+        fpr = fopen(argv[2], "r");
+        if (fpr == NULL) 
+        {
+            printf("Error in opening %s input file\n", argv[2]);
+        }
+    } 
+    else
+#endif
+    {
+        fpr = fopen(input_file_name, "r");
+        if (fpr == NULL) 
+        {
+            printf("Error in opening %s input file\n", input_file_name);
+        }
+        else
+        {
+            parse_config_file(fpr,&config_file);
+        }
+    }
+
+#endif
+
+    memset(&sa_info, 0, sizeof(sa_info));
+
+
+//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
+}
+#if 0 
+our_router = route_init();
+for (i=0;i<n_dst_ips;i++)
+{
+  route_add(our_router,&ip[i],&routes[i]);
+}
+#endif
+
+/*******************************************/
+/*************NETAPI STARTUP****************/
+/*******************************************/
+
+/* create netapi */
+netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);
+
+/* open the main heap */
+OurHeap = Pktlib_findHeapByName("netapi");
+if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}
+
+/* create two secondary heaps */
+/* Initialize the heap configuration. */
+memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
+
+pPktifTable = netapi_getPktlibIfTable();
+/* Populate the heap configuration */
+heapCfg.name                = "netapi-small";
+heapCfg.memRegion           = NETAPI_GLOBAL_REGION;
+heapCfg.sharedHeap          = 1;
+heapCfg.useStarvationQueue  = 0;
+heapCfg.dataBufferSize      = 512;
+heapCfg.numPkts             = 64;
+heapCfg.numZeroBufferPackets= 0;
+heapCfg.heapInterfaceTable.data_malloc  = pPktifTable->data_malloc;
+heapCfg.heapInterfaceTable.data_free    = pPktifTable->data_free;
+heapCfg.dataBufferPktThreshold   = 0;
+heapCfg.zeroBufferPktThreshold   = 0;
+
+specialSmall = Pktlib_createHeap(&heapCfg, &errCode);
+heapCfg.name                = "netapi-big";
+heapCfg.dataBufferSize      = 1600;
+specialLarge = Pktlib_createHeap(&heapCfg, &errCode);
+//register these heaps so poll routine will include their garbage queues.
+netapi_registerHeap(netapi_handle, specialSmall);
+netapi_registerHeap(netapi_handle, specialLarge);
+
+#ifdef REASSEMBLE_BENCH
+our_reassemble_bench(2);
+exit(1);
+#endif
+
+#ifndef EXPERIMENTAL
+/* create a pktio channel */
+our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb_bench, &our_chan_cfg,&err);
+if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}
+#endif
+
+/* 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);}
+#ifdef EXPERIMENTAL
+netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg,  &err);
+#else
+netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg,  &err);
+#endif
+if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
+
+#ifndef EXPERIMENTAL
+/* create a pktio channel for specially classified pkts */
+netcp_rx_chan2= pktio_create(netapi_handle, "classq", (PKTIO_CB) recv_cb, &netcp_rx_cfg2,  &err);
+if (!netcp_rx_chan2) {printf("pktio create RX2 failed err=%d\n",err); exit(1);}
+
+/* open netcp default tx, rx queues for sideband crypto */
+netcp_sb_tx_chan= pktio_open(netapi_handle, NETCP_SB_TX, NULL, &netcp_sb_tx_cfg,  &err);
+if (!netcp_sb_tx_chan) {printf("pktio open SB TX failed err=%d\n",err); exit(1);}
+netcp_sb_rx_chan= pktio_open(netapi_handle, NETCP_SB_RX, (PKTIO_CB) recv_sb_cb, &netcp_sb_rx_cfg,  &err);
+if (!netcp_sb_rx_chan) {printf("pktio open SB RX failed err=%d\n",err); exit(1);}
+#endif
+
+printf("net_test> %d bytes left in our CMA area\n", netapi_getBufMemRemainder());
+/* create scheduler instance */
+our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
+if (!our_sched) {printf("sched create failed\n"); exit(1);}
+
+#if 0
+/********************************************
+* Basic pkt loopback test
+*********************************************/
+printf("...running pure push/pop benchmark\n");
+our_pktio_bench(1000);
+our_pktio_bench(1000);
+our_pktio_bench(1000);
+our_pktio_bench(1000);
+our_pktio_bench(1000);
+/*********************************************/
+#endif
+
+
+
+
+/* add mac intefaces */
+netcp_cfgCreateMacInterface(
+                  netapi_handle,
+                  &config.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
+ip_rule0=netcp_cfgAddIp(
+                  netapi_handle,
+                  0,
+                  nwal_IPV4,
+                  &config.ip0,
+                  NULL,  //all IP
+                  (NETCP_CFG_ROUTE_HANDLE_T) NULL,
+                  &err
+                  );
+if (err) {printf("addip0 failed %d\n",err); exit(1); } 
+
+//create a 2nd mac instance
+netcp_cfgCreateMacInterface(
+                  netapi_handle,
+                  &config.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
+ip_rule1=netcp_cfgAddIp(
+                  netapi_handle,
+                  1,
+                  nwal_IPV4,
+                  &config.ip1,
+                  NULL,  //all IP
+                  (NETCP_CFG_ROUTE_HANDLE_T) NULL,
+                  &err
+                  );
+if (err) {printf("addip1 failed %d\n",err); exit(1); }
+
+#ifndef EXPERIMENTAL
+//attach 2 classifiers to iface 0, ip0
+class_0_cfg.u.c_l4.ip = ip_rule0;
+class_0 =  netcp_cfgAddClass(netapi_handle,
+                             &class_0_cfg,
+                             NULL,
+                             NETCP_CFG_ACTION_TO_SW,
+                            &err);
+if (err) {printf("addclass0 failed %d\n",err); exit(1);}
+
+class_1_cfg.u.c_l4.ip = ip_rule0;
+class_1 =  netcp_cfgAddClass(netapi_handle,
+                             &class_1_cfg,
+                             NULL,
+                             NETCP_CFG_ACTION_TO_SW,
+                             &err);
+if (err) {printf("addclass1 failed %d\n",err); exit(1);}
+
+
+//3rd classifier has a different IP and route
+class_2_cfg.u.c_l3_l4.ip_addr = &config.ip2;
+
+//create specialFlow for this classifier
+{
+Pktlib_HeapHandle heaps[2];
+int sizes[2];
+heaps[0]= specialSmall;
+heaps[1]= specialLarge;
+#define SPECIAL_SOP_OFF 128
+sizes[0]=512-SPECIAL_SOP_OFF;
+sizes[1]=1600-SPECIAL_SOP_OFF;
+#if 0
+specialFlow = netcp_cfgAddFlow( netapi_handle,
+                               2,
+                                heaps,
+                                sizes,
+                                SPECIAL_SOP_OFF,  //offset to start rx is 128 
+                                &err);
+if (err) {printf("add flow failed\n", err); exit(1);}
+#endif
+}
+#if 0
+//special route for this classifier:  different flow + destination q
+class2_route.p_dest_q = netcp_rx_chan2;
+class2_route.p_flow = specialFlow;
+class_2 = netcp_cfgAddClass(netapi_handle,
+                            &class_2_cfg,
+                            (void*) &class2_route,
+                            NETCP_CFG_ACTION_TO_SW,
+                            &err);
+if (err) {printf("addclass2 failed %d\n",err); exit(1);}
+#endif
+
+#endif
+//security stuff 
+    p_trie_sa = trie_new();
+   if (!p_trie_sa) {printf("trie alloc for SA  failed\n"); exit(1);}
+
+
+
+    for (i=0; i < MAX_SEC_INDEX;i++)
+    {
+        ourRXKeyParams[i].pEncKey = &ourEncrKey[0];
+        ourRXKeyParams[i].pAuthKey = &ourAuthKey[0];
+        memcpy(&(rx_sa[i].src), &config.remote_ipsec_ip,4);
+        memcpy(&(rx_sa[i].dst), &config.local_ipsec_ip,4);
+
+        build_sa_db(i);
+        sa_info[i].rx_tunnel = netapi_secAddSA(
+            netapi_handle,
+            config.ipsec_if_no, //iface #0 
+            &rx_sa[i],
+            &ourRXKeyParams[i],
+            config.ipsec_mode_rx == IPSEC_MODE_RX_SIDEBAND ? NETAPI_SEC_SA_SIDEBAND: NETAPI_SEC_SA_INFLOW,
+                NULL,  //use default route 
+            &(sa_info[i].rx_data_mode_handle),
+            &(sa_info[i].rx_inflow_mode_handle),
+            &err);
+        if (err) {printf("addRxSa failed %d\n",err); exit(1);}
+
+        if (config.ipsec_mode_rx == IPSEC_MODE_RX_INFLOW)
+        {
+            //assume inner and outer ip is the same
+            rx_policy[i]= netapi_secAddRxPolicy( netapi_handle,
+                             sa_info[i].rx_tunnel,  //link to tunnel above
+                             4,         //ipv4
+                             &config.remote_ipsec_ip, //src -> them
+                             &config.local_ipsec_ip,  //dst -> us
+                            NULL,  // no qualifiers
+                            NULL,  //default route
+                             &err);
+            if (err) {printf("addSaPolicy failed  %d, for index %d\n",err,i); exit(1);}
+        }
+        else 
+        {
+            rx_policy[i] = 0;
+             
+        }
+#ifdef NET_TEST_ENABLE_SIDE_BAND_LOW_LEVEL_API
+    /* Remember the NetCP Command Label so save cycles per Crypto 
+     * operation
+     * 
+     */
+    if(config.ipsec_mode_rx == IPSEC_MODE_RX_SIDEBAND)
+    {
+            nwalRetVal =  
+            nwal_initDMPSCmdInfo(PKTIO_GET_NWAL_INSTANCE(netcp_sb_rx_chan),
+                                 sa_info[i].rx_data_mode_handle,
+                                 &sa_info[i].rx_dmPSCmdInfo);
+    }
+
+#endif
+    }
+
+//tx SA
+//security stuff 
+     for (i=0; i < MAX_SEC_INDEX;i++)
+    {
+    ourTXKeyParams[i].pEncKey = &ourEncrKey[0];
+    ourTXKeyParams[i].pAuthKey = &ourAuthKey[0];
+    memcpy(&(tx_sa[i].src), &config.local_ipsec_ip,4);
+    memcpy(&(tx_sa[i].dst), &config.remote_ipsec_ip,4);
+    sa_info[i].tx_tunnel = netapi_secAddSA( netapi_handle,
+                 0, //iface #0 
+                &(tx_sa[i]),
+                &ourTXKeyParams[i],
+                config.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND ? NETAPI_SEC_SA_SIDEBAND: NETAPI_SEC_SA_INFLOW,
+                NULL,  //use default route 
+                &(sa_info[i].tx_data_mode_handle),
+                &(sa_info[i].tx_inflow_mode_handle),
+                &err);
+if (err) {printf("addTxSa failed %d\n",err); exit(1);}
+
+#ifdef NET_TEST_ENABLE_SIDE_BAND_LOW_LEVEL_API
+    /* Remember the NetCP Command Label so save cycles per Crypto 
+     * operation
+     * 
+     */
+    if(config.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND)
+    {
+            nwalRetVal =  
+            nwal_initDMPSCmdInfo(PKTIO_GET_NWAL_INSTANCE(netcp_sb_tx_chan),
+                                 sa_info[i].tx_data_mode_handle,
+                                 &sa_info[i].tx_dmPSCmdInfo);
+    }
+
+#endif
+    }
+
+#ifdef TEST_TIMERS
+//timers
+ourTimerBlock = hplib_Timer_CreateGroup(
+        netapi_handle,
+        "our1sttimer",
+        our_timer_cb,
+        0,    //1 if timers local to thread
+        0,    //1 if expect to cancel
+        hplib_getTicksPerSec()/1000,  /* 1 msc resolution for these timers */
+        hplib_getTicksPerSec()/5000, /* would like .5 msc tolerence */
+        10);  //small # of timers to test garbage collection
+if (err) {printf("hplib_Timer_CreateGroup() failed %d\n",err); exit(1);}
+
+//start a couple of timers 
+t1 = hplib_Timer_Start(
+        ourTimerBlock,
+        (void *) 1,
+        100LL,  //timer group ticks
+        &err);
+if (err) {printf("timerstart failed %d\n");}
+t2 = hplib_Timer_Start(
+        ourTimerBlock,
+        (void *) 2,
+        200LL,  //timer group ticks
+        &err);
+if (err) {printf("timerstart failed %d\n");}
+t3 = hplib_Timer_Start(
+        ourTimerBlock,
+        (void *) 3,
+        300LL,  //timer group ticks
+        &err);
+if (err) {printf("timerstart failed %d\n");}
+#endif
+netcp_cfgReqStats(netapi_handle, our_stats_cb, 1,&err);
+if (err!=0) {printf("stats req failed\n");}
+
+/*********************************************/
+/*****************end NETAPI STARTUP**********/
+/*********************************************/
+
+
+#if 0
+/********************************************
+* Basic pkt loopback test
+*********************************************/
+printf("...runnining pure push/pop benchmark\n");
+our_pktio_bench(100);
+#endif
+
+/**************unused stuff******************/
+#if 0
+/* 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);
+#endif
+
+/*********************************************/
+/**************Entry point into scheduler ****/
+/*********************************************/
+netapi_schedWaitForEvents(our_sched, &err);
+
+/* done */
+our_stats_cb(netapi_handle, NULL);
+
+
+#define DO_FAST_POLL
+#ifdef DO_FAST_POLL
+//example_fast_pushpop(OurHeap, 500);
+//example_fast_poll(netcp_rx_chan,20000);
+#endif
+
+/*************************************************
+ ************CLEAN UP****************************
+ ************************************************/
+
+#ifndef EXPERIMENTAL
+//delete Classifiers
+netcp_cfgDelClass(netapi_handle, class_0, &err); 
+netcp_cfgDelClass(netapi_handle, class_1, &err); 
+//netcp_cfgDelClass(netapi_handle, class_2, &err); 
+
+#if 0
+//delete flow 
+netcp_cfgDelFlow(netapi_handle, specialFlow, &err);
+#endif
+#endif
+#if 1
+//delete policy
+     for (i=0; i < MAX_SEC_INDEX;i++)
+    {
+        if (rx_policy[i])
+            netapi_secDelRxPolicy(netapi_handle, rx_policy[i], &err);
+     
+        //delete tunnels
+        netapi_secDelSA(netapi_handle, 0, sa_info[i].rx_tunnel, &err);
+        netapi_secDelSA(netapi_handle, 0, sa_info[i].tx_tunnel, &err);
+#endif
+    }
+//delete IPs and MAC Interfacess
+netcp_cfgDelIp(netapi_handle, 0, 0, NULL, NULL, ip_rule0, &err);
+netcp_cfgDelIp(netapi_handle, 1, 0, NULL, NULL, ip_rule1, &err);
+netcp_cfgDelMac(netapi_handle,0,&err);
+netcp_cfgDelMac(netapi_handle,1,&err);
+
+
+//close pktio channels we opened
+pktio_close(netcp_tx_chan ,&err);
+pktio_close(netcp_rx_chan ,&err);
+#ifndef EXPERIMENTAL
+pktio_close(netcp_sb_tx_chan ,&err);
+pktio_close(netcp_sb_rx_chan ,&err);
+
+//clear pktio channel we created
+pktio_control(our_chan, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channel_control, &err);
+pktio_control(netcp_rx_chan2, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channel_control, &err);
+
+//delete pktio channels we created
+pktio_delete(our_chan, &err);
+pktio_delete(netcp_rx_chan2,&err);
+#endif
+netapi_shutdown(netapi_handle);
+
+}
+
+//EXAMPLE FAST POLL
+/* PLD */
+void netapi_pld(void * x)
+{   
+           asm volatile("pld [r0]");
+}
+#include "ti/drv/nwal/nwal_util.h"
+
+#define M 1008
+static int l3_off[M], l4_off[M], L3_chk_ok[M], L4_chk_ok[M], len[M] ;
+static nwal_AppId appid[M];
+static unsigned char * buf[M];
+#define N2POLL 8 //batch size
+#define NTOPOP 190
+Ti_Pkt * pHd[NTOPOP];
+void example_fast_pushpop(Pktlib_HeapHandle h , int n_trials)
+{
+int i,j;
+unsigned long t1;
+unsigned long t2;
+unsigned long sumf=0;
+unsigned long sumt=0;
+unsigned long sump=0;
+#define NTOPOP 190
+Ti_Pkt * tempVA;
+Qmss_QueueHnd freeQ=Pktlib_getInternalHeapQueue(h);
+
+//n_trials of NTOPOP actions
+for(i=0;i<n_trials;i++)
+{
+    //raw pop
+    t1= hplib_mUtil_GetTickCount();
+    pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (freeQ));
+    for(j=1;j<NTOPOP;j++)
+    {
+       tempVA  =  hplib_mVM_PhyToVirt(pHd[j-1]);
+       netapi_pld(tempVA);
+        //__builtin_prefetch(tempVA);
+       pHd[j] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (freeQ));
+       sumf+= (int) (   ((Cppi_HostDesc *) tempVA)->origBuffPtr -
+                  ((Cppi_HostDesc *) tempVA)->buffPtr);
+    }
+    tempVA  =  hplib_mVM_PhyToVirt(pHd[j-1]);
+    sumf+= (int) (   ((Cppi_HostDesc *) tempVA)->origBuffPtr -
+                  ((Cppi_HostDesc *) tempVA)->buffPtr);
+    t2=hplib_mUtil_GetTickCount();
+    sumt+= (t2-t1);
+
+    //invalidate/wb 
+    for(j=0;j<NTOPOP;j++)
+    {
+        tempVA  =  hplib_mVM_PhyToVirt(pHd[j]);
+        hplib_CacheWbInv(tempVA,128);
+    }
+
+    //raw push 
+    t1=hplib_mUtil_GetTickCount();
+    for(j=0;j<NTOPOP;j++)
+    {
+        PKTIO_QMSS_QUEUE_PUSH_DESC_SIZE_RAW (freeQ,
+                                             (void *) pHd[j],
+                                             128);
+    }
+    t2=hplib_mUtil_GetTickCount();
+    sump += (t2-t1);
+}
+printf("\nfast poppush: np=%d  pop=%d  push=%d sumf=%d\n", (n_trials*NTOPOP),
+        sumt/(n_trials*NTOPOP),  sump/(n_trials*NTOPOP), sumf);
+sleep(1);
+return;
+}
+
+
+
+void example_fast_poll( PKTIO_HANDLE_T * p_pktio, int max_pkts)
+{
+int j=0;
+int jj=0;
+int i,k,l=0,ltot=0;
+int n= N2POLL; //max # of pkts to poll
+Ti_Pkt * tempVA;
+pasahoLongInfo_t* pinfo;
+unsigned long t1;
+unsigned long t2;
+unsigned long t11;
+unsigned long t12;
+unsigned long np;
+unsigned long sumt=0;
+unsigned long sumf=0;
+unsigned long sump=0;
+unsigned long totlen=0;
+int max_batch=0;
+
+//this should  be done once and saved
+Qmss_QueueHnd rxQ= PKTIO_GET_DEFAULT_NETCP_Q(p_pktio);
+Qmss_QueueHnd freeQ;
+//loop forever
+for(;max_pkts>0;)
+{
+    t1= hplib_mUtil_GetTickCount();
+    pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
+    if (!pHd[0]) continue;
+    //got pkt
+    for(i=1;(i<n) && (pHd[i-1]);i++)
+    {
+        //convert previous descriptor PA -> VA
+        tempVA  =  hplib_mVM_PhyToVirt(pHd[i-1]); 
+
+        //try and preload desriptor
+         __builtin_prefetch(tempVA);
+        //netapi_pld(tempVA);
+
+        //read next descriptor from queue 
+        pHd[i] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
+#if 1   
+        /* extract some meta data */
+        Cppi_getData (Cppi_DescType_HOST, (Cppi_Desc*)tempVA, &buf[jj], &len[jj]);
+        pinfo =  nwal_mGetProtoInfo(tempVA);
+        l3_off[jj]= nwal_mGetL3OffBytes(pinfo);
+        l4_off[jj]= nwal_mGetL4Offset(pinfo);
+        if(nwal_mGetAppidFmPkt(tempVA,&appid[jj]) != nwal_TRUE)
+        {
+            printf("ERROR!!!! AppID not available in incoming packet \n");
+        }
+//#define VERIFY_SOP
+#ifdef VERIFY_SOP
+  if (sump < 200)  printf("..sop off=%d\n", (int) buf[jj]-
+           (int)  ((Cppi_HostDesc *) tempVA)->origBuffPtr) ;
+#endif
+#endif
+        jj+=1;
+    }
+    //finish last pkt in burst
+    if(pHd[i-1])
+    {
+        //convert previous descriptor PA -> VA
+        tempVA  =  hplib_mVM_PhyToVirt(pHd[i-1]); 
+
+        /* extract some meta data */
+#if 1
+        pinfo =  nwal_mGetProtoInfo(tempVA);
+        l3_off[jj]= nwal_mGetL3OffBytes(pinfo);
+        l4_off[jj]= nwal_mGetL4Offset(pinfo);
+        if(nwal_mGetAppidFmPkt(tempVA,&appid[jj]) != nwal_TRUE)
+        {
+            printf("ERROR!!!! AppID not available in incoming packet \n");
+        }
+#endif
+        //get ptr (Physical address) and length of associate buffer
+        Cppi_getData (Cppi_DescType_HOST, (Cppi_Desc*)tempVA, &buf[jj], &len[jj]);
+        jj+=1;
+    }
+    t2= hplib_mUtil_GetTickCount();
+    j+=(pHd[i-1]? i: (i-1)) ;
+    if (jj>(M-n)) jj=0;
+    l+=1;  //n batches
+    ltot+=1;
+    if(pHd[i-1])
+    {
+      if (i>max_batch) max_batch= i;
+    }
+    else
+    {
+      if( (i-1) >max_batch) max_batch = i-1;
+    }
+
+    //cleanup
+    //printf("cleanup %d\n",i);
+    for(k=0;k<i;k++)
+    {
+        //cleanup.  need to covert all of desriptor to VA so that i can use freePacket() 
+        //alternative would be to just do cache ops plus descriptor raw push to pktlib
+        // heap free queue
+        if(pHd[k])
+        {
+
+        //tempVA=Qmss_osalConvertDescPhyToVirt(pHd[k]);
+        tempVA  =  hplib_mVM_PhyToVirt(pHd[k]);
+        freeQ=Qmss_getQueueHandle(Cppi_getReturnQueue (Cppi_DescType_HOST, (Cppi_Desc *)tempVA));
+        hplib_CacheWbInv(tempVA,128);
+        //would need to wbInv buffer also in practice. Also need to walk
+        // descriptor chain 
+        t11= hplib_mUtil_GetTickCount();
+       // Pktlib_freePacket(tempVA);
+        PKTIO_QMSS_QUEUE_PUSH_DESC_SIZE_RAW (freeQ,
+                                             (void *) pHd[k],
+                                             128);
+
+        t12= hplib_mUtil_GetTickCount();
+        sumf += (t12-t11);       
+        }
+    }
+    sumt += (t2-t1);
+    sump +=(pHd[i-1]? i: (i-1));
+    max_pkts -= (pHd[i-1]? i: (i-1));
+
+    //printf("end cleanup %d %d %d\n",sumt,sumf,sump );
+    if (sump > 10000) {
+       printf("pkts rx %d batches=%d  appid=%x l3_off=%d l4_off=%d len=%d buf=0x%x rxcycle= %d pkts/batchx1000=%d maxbatch=%d cycles per rawpush = %d\n", 
+                  j,ltot, appid[j%M], 
+                  l3_off[j%M],l4_off[j%M],  
+                  len[j%M],buf[j%M],
+                   sumt/sump,  (sump*1000)/l, max_batch,
+                   sumf/sump);
+       sumt=sump=sumf=0;
+       l=0;
+    }
+}
+
+    //cleanup any remaining buffers
+    for(;;)
+    {
+        pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
+        if(!pHd[0]) break;
+       tempVA  =  Osal_qmssPhyToVirt(pHd[0]);
+        freeQ=Qmss_getQueueHandle(Cppi_getReturnQueue (Cppi_DescType_HOST, (Cppi_Desc *)tempVA));
+        hplib_CacheWbInv(tempVA,128);
+        PKTIO_QMSS_QUEUE_PUSH_DESC_SIZE_RAW (freeQ,
+                                             (void *) pHd[0],
+                                             128);
+    }
+}
+
+#ifdef EXPERIMENTAL
+
+static inline void send_it(Ti_Pkt *tip, int len, ROUTE_SEC_T * p_sec)
+{
+  unsigned long st1;
+  unsigned long st2;
+  int err=0;
+  PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
+  nwalTxPktInfo_t meta_tx2={0};
+  st1=hplib_mUtil_GetTickCount();
+  if (len<60) 
+  { 
+     unsigned int templen;
+     char * p_pkt;
+     len=60; 
+     Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
+     Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
+     stats.tx_min+=1;
+  }
+  Pktlib_setPacketLen(tip,len);
+  meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
+  meta_tx2.startOffset = 0;
+  meta_tx2.ipOffBytes = 14;
+  meta_tx2.ploadLen = len ;
+  if(p_sec)
+  {   
+       meta_tx2.txFlag1 |= NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO ;
+       meta2.sa_handle=p_sec->tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied
+       meta_tx2.enetPort=0;
+       meta_tx2.saOffBytes=14+20;
+       meta_tx2.saPayloadLen=len-14-20;   //don't include tag, mac and outer header
+       stats.sec_tx+=1;
+  }
+  meta2.u.tx_meta=&meta_tx2;
+  pktio_send(netcp_tx_chan,tip,&meta2,&err);
+  stats.tx +=1;
+  st2=hplib_mUtil_GetTickCount();
+  stats.send_cycles += (unsigned long long) (st2-st1);  
+} 
+void recv_cb_router(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;
+Ti_Pkt * tip;
+unsigned int templen;
+char * p_pkt;
+HEAD_T temp_head;
+unsigned int appid;
+IP_HEAD_T th;
+ROUTE_SEC_T *sec_data=NULL;
+unsigned long t1;
+unsigned long t2;
+unsigned long ct1;
+unsigned long ct2;
+unsigned short ip_pl;
+int n_c_ops;
+t1=hplib_mUtil_GetTickCount();
+ct1 =Osal_cache_op_measure(&n_c_ops);
+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)-4;//real length, subtract mac trailer
+        stats.rx+=1;
+        appid = ((unsigned int)meta[i].u.rx_meta->appId)&0xff000000;
+        switch(appid)
+        {
+           case(NETAPI_NETCP_MATCH_IPSEC):
+           case(NETAPI_NETCP_MATCH_IPSEC_POLICY):
+           {
+             int tailen=12+2;
+             memcpy(&temp_head,&p_pkt[14],sizeof(HEAD_T));
+             if (!check_header(&temp_head,&meta[i])) {
+                stats.n_bad+=1;
+                Pktlib_freePacket(tip); 
+                continue;
+             }
+             tailen+=p_pkt[len-12-2]; //padding length  (12)should come from sec_ptr
+             p_pkt = &p_pkt[8+16+20];   //16= iv len, should come from sec_ptr
+             len -= (8+16+20+tailen);  //16= iv len should come from sec ptr
+            
+             //now check inner headder.
+             memcpy(&th,&p_pkt[14],20);
+             if (!check_header(&temp_head,&meta[i])) {
+                stats.n_bad+=1;
+                Pktlib_freePacket(tip);
+                continue;
+             }
+             Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
+             Pktlib_setPacketLen(tip,len);
+             
+             if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data)<0)
+              {
+                stats.n_bad+=1;
+                Pktlib_freePacket(tip);
+             }
+             else
+             {
+               send_it(tip,len,sec_data);
+             }
+             break;
+           }
+           case(NETAPI_NETCP_MATCH_GENERIC_MAC):
+              if((p_pkt[12]!=0x8)||(p_pkt[13]!=0x00)) 
+              {
+                stats.n_new+=1;
+                Pktlib_freePacket(tip); 
+                continue;
+              }
+              if (!check_header(&temp_head,&meta[i])) 
+              {
+                stats.n_bad+=1;
+                Pktlib_freePacket(tip);
+                continue;
+              }
+              memcpy(&th,&p_pkt[14],20);
+              ip_pl= (((unsigned char *)&th.w1)[2]<<8) | ((unsigned char *)&th.w1)[3];
+              if ((ip_pl+14)<60)
+              {
+                len-= (60-(ip_pl+14));
+                stats.rx_min+=1;
+              }
+              Pktlib_setPacketLen(tip,len);
+              if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data)<0)
+              {
+                stats.n_bad+=1;
+                Pktlib_freePacket(tip);
+              }
+              else
+              {
+                 send_it(tip,len,sec_data);
+              }
+              break;
+           case(NETAPI_NETCP_MATCH_GENERIC_IP):
+              Pktlib_freePacket(tip); 
+              stats.n_new=1;
+              break;
+           default:
+              stats.n_new+=1;
+              Pktlib_freePacket(tip);
+              break;
+       }
+}
+t2=hplib_mUtil_GetTickCount();
+ct2 =Osal_cache_op_measure(&n_c_ops);
+stats.app_cycles +=  (unsigned long long) (t2-t1);
+stats.tx_cache_cycles += (unsigned long long) (ct2-ct1);
+return;
+}
+#endif