Update packet length in recv_cb to subtract out 4 byte CRC
[keystone-rtos/netapi.git] / ti / runtime / netapi / test / net_test.c
1 /******************************************
2  * File: net_test.c
3  * Purpose: test app for netapi
4  **************************************************************
5  * FILE:  net_test.c
6  * 
7  * DESCRIPTION:  netapi user space transport
8  *               library  test application
9  * 
10  * REVISION HISTORY:  rev 0.0.1 
11  *
12  *  Copyright (c) Texas Instruments Incorporated 2010-2011
13  * 
14  *  Redistribution and use in source and binary forms, with or without 
15  *  modification, are permitted provided that the following conditions 
16  *  are met:
17  *
18  *    Redistributions of source code must retain the above copyright 
19  *    notice, this list of conditions and the following disclaimer.
20  *
21  *    Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the 
23  *    documentation and/or other materials provided with the   
24  *    distribution.
25  *
26  *    Neither the name of Texas Instruments Incorporated nor the names of
27  *    its contributors may be used to endorse or promote products derived
28  *    from this software without specific prior written permission.
29  *
30  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
31  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
32  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
34  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
35  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
36  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
39  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
40  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  *****************************************/
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <string.h>
50 #include "trie.h"
51 #include "string.h"
52 #include "netapi.h"
53 #include "pktio.h"
54 #include <sys/resource.h>
55 #include "net_test.h"
56 #include <ti/drv/sa/salld.h>
57 #define EXPERIMENTAL
58 #ifdef EXPERIMENTAL
59 #include "router.c"
60 Trie * our_router;
62 OUR_ROUTE_T routes[MAX_ROUTES]=
63 {
64 {0,{0xD4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x14,0x02,0x08,0x00},0},
65 {0,{0x00,0x00,0x0,0x00,0x0,0x0, 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00},0},
66 {0,{0xD4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x14,0x02,0x08,0x00},0},
67 {0,{0x00,0x15,0x60,0xa1,0xf7,0xbe, 0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00},0},
68 {0,{0xd4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00},0}};
70 unsigned int ip[MAX_ROUTES]={BE(0x0a0100c8),BE(0x0a00000a),BE(0x0a02000a),BE(0xc0a8010a),BE(0x9eda6719)};
72 #endif
73 //#define TEST_TIMERS
75 /*************debug********************/
76 void dump_descr(unsigned long *p, int n)
77 {
78    printf("--------dump of descriptor %d %x\n", n, (int) p);
79    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]);
80    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]);
81    printf("-----------------------------\n");
82 }
83 void dump_header(unsigned long *p, int n, int a, int r)
84 {
85    printf("--------dump of header %d %x appID=%x flag1=%x\n", n, (int) p,a,r);
86    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]);
87    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]);
88    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]);
89    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]);
90    printf("-----------------------------\n");
91 }
93 /*****************************************/
96 //************for multi pkt burst  xfer test in loopback mode
97 #define TX_BURST 700 
98 int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;
99 nwalTxPSCmdInfo_t   flowPSCmdInfo;
101 //this device: 10.0.0.100, mac 0x,01,02,03,04,05  and .. 0x6
103 //test packet, setup for loopback (so dest is ourself)
104 static uint8_t testPkt[] = {
106   /* MAC header */
107   0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
108   0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04,
109   0x08, 0x00,
111   /* IP header */
112   0x45, 0x00,
113   0x00, 0x6c,  /* Length (including this header) */
114   0x00, 0x00, 0x00, 0x00, 0x05, 0x11,
115   0x00, 0x00,  /* Header checksum */
116   0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x64,
118   /* UDP header */
119   0x12, 0x34, 0x05, 0x55,
120   0x00, 0x58,  /* Length, including this header */
121   0x00, 0x00,  /* Header checksum */
123  /* Payload */
124   0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
125   0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
126   0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
127   0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
128   0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
129   0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,
130   0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
131   0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
132   0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
133   0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81
135 };
137 char    input_file_name[] = "net_test_config.txt";
138 #define MAX_LINE_LENGTH 40
140 #define TEST_PAYLOAD_LEN            80
142 #define TEST_PKT_IP_OFFSET_BYTES        14
143 #define TEST_PKT_UDP_OFFSET_BYTES       34
144 #define TEST_PKT_PLOAD_OFFSET_BYTES     42
145 #define TEST_PKT_UDP_HDR_LEN            8
146 /* Offsets to length fields */
147 #define TEST_PKT_OFFSET_IP_LEN      16
148 #define TEST_PKT_OFFSET_UDP_LEN     38
150 #define TEST_PKT_LEN                122
152 /* The pseudo header checksum of the packet except for the 16 bit length */
153 #define TEST_PKT_PSEUDO_HDR_CHKSUM_SANS_LEN  0x0FFC
155 void example_fast_poll( PKTIO_HANDLE_T * p_pktio, int max_pkts);
156 void example_fast_pushpop(Pktlib_HeapHandle p_heap, int ntrials);
158 void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
159                          PKTIO_METADATA_T meta[], int n_pkts,
160                          uint64_t ts );
163 //#include "arpa/inet.h"
164 long htonl(long x)
166         long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 |  (x&0xff)<<24 ;
167         return temp;
170 /********************************************************************
171  *  FUNCTION PURPOSE: Ones complement addition utility
172  ********************************************************************
173  ********************************************************************/
174 uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2)
176   uint32_t result;
178   result = (uint32_t)v1 + (uint32_t)v2;
179   result = (result >> 16) + (result & 0xffff);
180   result = (result >> 16) + (result & 0xffff);
182   return ((uint16_t)result);
185 /********************************************************************
186  *  FUNCTION PURPOSE: Ones complement checksum utility
187  ********************************************************************
188  ********************************************************************/
189  uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords)
191   uint16_t chksum = 0;
192   uint16_t v;
193   uint32_t i;
194   uint32_t j;
196   for (i = j = 0; i < nwords; i++, j+=2)  {
197     v = (p[j] << 8) | p[j+1];
198     chksum = test_utilOnesComplementAdd (chksum, v);
199   }
200   return (chksum);
201 } /* utilOnesCompChkSum */
203 /**************************************************************************************
204  * FUNCTION PURPOSE: Compute ipv4 psudo checksum
205  **************************************************************************************
206  * DESCRIPTION: Compute ipv4 psudo checksum
207  **************************************************************************************/
208 uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen)
210   uint16_t psudo_chksum;
212   psudo_chksum = test_utilOnesCompChkSum (&data[12], 4);
213   psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]);
214   psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen);
216   return (psudo_chksum);
218 } /* utilGetIpv4PsudoChkSum */
222 /* net test default configuration */
223 netTestConfig_t config =
225     {0x00,0x01,0x02,0x03,0x05,0x05},
226     {0x00,0x01,0x02,0x03,0x05,0x06},
227     {10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
228     {10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
229     {10, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
230     {192,168 , 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
231     {192,168 , 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
232     IPSEC_MODE_RX_SIDEBAND,
233     IPSEC_MODE_TX_SIDEBAND,
234     0
235 };
237 #if 1  //goes with real tx (to laptop) 
238 unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,
239                       0x00,0x01,0x02,0x03,0x04,0x05,
240                       0x08,0x00};
241 unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa};
242 #endif
244 #if 0  //goes with loopback
245 unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05, 
246                       0x00,0x11,0x22,0x33,0x44,0x55,
247                       0x08,0x00};
248 #endif
249 #define NE 65536 
250 HEAD_T *nat;
252 #define NP 5000
253 int n_pkt = NP;
254 STATS_T stats;
256 Trie * P_trie;
257 Trie *p_trie_sa;
258 HEAD_T pkts[NP];
259 #define PERSLOW  10  //% of pkts that will not be fastpath'd 
260 int perslow= PERSLOW;
262 /*******************************************
263  *************NETAPI OBJECTS***************
264  *****************************************/
265 static NETAPI_CFG_T our_netapi_default_cfg=
267 TUNE_NETAPI_PERM_MEM_SZ,
268 128,  //start of packet offset for hw to place data on rx for default flow
269 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
270 TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
271 TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
272 64, //#descriptors w/o buffers in default heap
273 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
274 128   ,  //tail room
275 256      //extra room 
276 };
278 Pktlib_HeapHandle OurHeap;
279 Pktlib_HeapHandle specialSmall;
280 Pktlib_HeapHandle specialLarge;
282 PKTIO_HANDLE_T *our_chan;
283 PKTIO_HANDLE_T *netcp_rx_chan;
284 PKTIO_HANDLE_T *netcp_rx_chan2;
285 PKTIO_HANDLE_T *netcp_tx_chan;
286 PKTIO_HANDLE_T *netcp_sb_tx_chan;
287 PKTIO_HANDLE_T *netcp_sb_rx_chan;
288 PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
289 PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
290 PKTIO_CFG_T netcp_rx_cfg2={PKTIO_R, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8};
291 PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
292 PKTIO_CFG_T netcp_sb_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
293 PKTIO_CFG_T netcp_sb_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
295 void house(NETAPI_SCHED_HANDLE_T *s);
296 NETAPI_T netapi_handle;
297 NETAPI_SCHED_HANDLE_T * our_sched;
298 NETAPI_SCHED_CONFIG_T our_sched_cfg={
299   NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000  //every 5000000 poll loops
300 };
301 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
302 NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock; 
303 NETAPI_TIMER_T t1;
304 NETAPI_TIMER_T t2;
305 NETAPI_TIMER_T t3;
307 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
308         int n_fired,     //# timers fired
309         NETAPI_TIMER_LIST_T fired_list,
310         uint64_t currentTime);
312 NETCP_CFG_IP_T ip_rule0;
313 NETCP_CFG_IP_T ip_rule1;
314 NETCP_CFG_CLASS_T class_0;
315 NETCP_CFG_CLASS_T class_1;
316 NETCP_CFG_CLASS_T class_2;
317 NETCP_CFG_FLOW_HANDLE_T specialFlow;
319 NETCP_CFG_CLASSIFIER_T class_0_cfg=
321    NETCP_CFG_CLASS_TYPE_L4,
322    {
323         {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2500}}
324    }
325 };
327 NETCP_CFG_CLASSIFIER_T class_1_cfg=
329    NETCP_CFG_CLASS_TYPE_L4,
330    {
331         {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2502}}
332    }
333 };
335 NETCP_CFG_ROUTE_T  class2_route=
337 NULL, NULL  //* to be filled in
338 };
339 NETCP_CFG_CLASSIFIER_T class_2_cfg=  
341    NETCP_CFG_CLASS_TYPE_L3_L4,
342    {
343         {0,  4 ,0/*fill in below*/ , NULL, NULL,          //L2/L3
344            NWAL_APP_PLOAD_PROTO_UDP, {2504}}   //L4
345    }
346 };
348 PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};
350 /* security objects. (for loopback mode) */
351 netTestSA_t sa_info[6];
352 int netapi_algorithm_set = 0;
353 int netapi_sec_sa_mode = 2;
354 /* tmannan-end */
355 //NETCP_CFG_SA_T rx_tunnel;
356 //NETCP_CFG_SA_T tx_tunnel;
357 NETCP_CFG_IPSEC_POLICY_T rx_policy[4];
358 //void * rx_data_mode_handle;
359 //void * tx_data_mode_handle;
360 //void * rx_inflow_mode_handle;
361 //void * tx_inflow_mode_handle;
362 /* rx */
365 NETAPI_SEC_SA_INFO_T rx_sa [4] = {
367     NWAL_SA_DIR_INBOUND,
368     0x11111111,  //spi
369     nwal_IpSecProtoESP, //ESP mode
370     nwal_SA_MODE_TUNNEL,  //tunnel mode
371     nwal_IPV4, //v4
372     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
373     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
374     64,/* replayWindow */
375     NWAL_SA_AALG_HMAC_SHA1,
376     NWAL_SA_EALG_AES_CBC,
377     0,0  //na
378 },
380     NWAL_SA_DIR_INBOUND,
381     0x22222222,  //spi
382     nwal_IpSecProtoESP, //ESP mode
383     nwal_SA_MODE_TUNNEL,  //tunnel mode
384     nwal_IPV4, //v4
385     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
386     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
387     64,/* replayWindow */
388     NWAL_SA_AALG_HMAC_SHA2_256,
389     NWAL_SA_EALG_AES_CTR,
390     0,0  //na
391 },
393     NWAL_SA_DIR_INBOUND,
394     0x33333333,  //spi
395     nwal_IpSecProtoESP, //ESP mode
396     nwal_SA_MODE_TUNNEL,  //tunnel mode
397     nwal_IPV4, //v4
398     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
399     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
400     64,/* replayWindow */
401     NWAL_SA_AALG_HMAC_SHA2_256,
402     NWAL_SA_EALG_3DES_CBC,
403     0,0  //na
404 },
406     NWAL_SA_DIR_INBOUND,
407     0x44444444,  //spi
408     nwal_IpSecProtoESP, //ESP mode
409     nwal_SA_MODE_TUNNEL,  //tunnel mode
410     nwal_IPV4, //v4
411     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (them) -> set below */
412     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (us)-> set below*/
413     64,/* replayWindow */
414     NWAL_SA_AALG_HMAC_MD5,
415     NWAL_SA_EALG_NULL,
416     0,0  //na
418 };
420 /*tx */
421 NETAPI_SEC_SA_INFO_T tx_sa[4]= {
423     NWAL_SA_DIR_OUTBOUND,
424     0x11111111,  //spi
425     nwal_IpSecProtoESP, //ESP mode
426     nwal_SA_MODE_TUNNEL,  //tunnel mode
427     nwal_IPV4, //v4
428     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (us) -> set below */
429     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (them) -> set below*/
430     64, /* NA replayWindow */
431     NWAL_SA_AALG_HMAC_SHA1,
432     NWAL_SA_EALG_AES_CBC,
433     0,0  //seq no
434 },
435     {
436     NWAL_SA_DIR_OUTBOUND,
437     0x22222222,  //spi
438     nwal_IpSecProtoESP, //ESP mode
439     nwal_SA_MODE_TUNNEL,  //tunnel mode
440     nwal_IPV4, //v4
441     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (us) -> set below */
442     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (them) -> set below*/
443     64, /* NA replayWindow */
444     NWAL_SA_AALG_HMAC_SHA2_256,
445     NWAL_SA_EALG_AES_CTR,
446     0,0  //seq no
447 },
449     NWAL_SA_DIR_OUTBOUND,
450     0x33333333,  //spi
451     nwal_IpSecProtoESP, //ESP mode
452     nwal_SA_MODE_TUNNEL,  //tunnel mode
453     nwal_IPV4, //v4
454     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (us) -> set below */
455     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (them) -> set below*/
456     64, /* NA replayWindow */
457     NWAL_SA_AALG_HMAC_SHA2_256,
458     NWAL_SA_EALG_3DES_CBC,
459     0,0  //seq no
460 },
462     NWAL_SA_DIR_OUTBOUND,
463     0x44444444,  //spi
464     nwal_IpSecProtoESP, //ESP mode
465     nwal_SA_MODE_TUNNEL,  //tunnel mode
466     nwal_IPV4, //v4
467     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Src IP (us) -> set below */
468     { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* dst IP (them) -> set below*/
469     64, /* NA replayWindow */
470     NWAL_SA_AALG_HMAC_MD5,
471     NWAL_SA_EALG_NULL,
472     0,0  //seq no
474 };
476 static nwalSecKeyParams_t ourTXKeyParams[4] ={
478     16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/
479     20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA1 */
480     NULL, //set below
481     NULL, //set below
482 },
484     20, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_AES_CTR and 0 bytes Salt*/
485     32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */
486     NULL, //set below
487     NULL, //set below
488 },
490     24, /* encKeySize: DES-CBC: 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/
491     32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */
492     NULL, //set below
493     NULL, //set below
494 },
496     0, /* NULL*/
497     16, /* MD5, 16 bytes */
498     NULL, //set below
499     NULL, //set below
501 };
503 /* these keys are for aes-ctr and hmac sha2_256 */
504 static nwalSecKeyParams_t ourRXKeyParams[4] ={
506     16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/
507     20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA1 */
508     NULL, //set below
509     NULL, //set below
510 },
512     20, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_AES_CTR and 0 bytes Salt*/
513     32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */
514     NULL, //set below
515     NULL, //set below
516 },
518     24, /* encKeySize: DES-CBC: 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/
519     32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */
520     NULL, //set below
521     NULL, //set below
522 },
524     0, /* NWAL_SA_EALG_NULL*/
525     16, /* NWAL_SA_AALG_HMAC_MD5, 16 bytes */
526     NULL, //set below
527     NULL, //set below
529 };
532 static uint8_t ourAuthKey[36] =
533         {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
534          0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
535          0x20, 0x21, 0x22, 0x23 };
538 static uint8_t ourEncrKey[36] = 
539         {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
540          0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
541          0x30, 0x31, 0x32, 0x33 }; 
544 /*************************END NETAPI OBJECTS***********************/
546 #define START_SRC_IP 0x0a00000a
547 #define DST_IP       0xc0a80001
548 #define NEW_START_SRC_IP 0x9eda000a
549 #define DST_PORT 0x555 
550 #define START_SRC_PORT 0x1234
551 #define NEW_START_SRC_PORT 100
552 void update_header(HEAD_T * p_head, int len)
554    unsigned char *p = (unsigned char *) &p_head->udp[1];
555    len -= (20+14);
556    /* update ip checksum */
557    /* update udp checksum */
558    /* update length */
559    *p= (len&0xff00)>>8;
560    *(p+1) = len&0xff;
563 #if 0
564 void gen_pkts(int np)
566 int i;
567 int ip = START_SRC_IP &0xff;
568 int port= START_SRC_PORT;
569 //HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP},
570 //             {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}};
571 HEAD_T temp;
572 memcpy(&temp,&testPkt[0],sizeof(HEAD_T));
574 for(i=0;(i<np) && (i<NP);i++)
575   {
576        memcpy(&pkts[i],&temp,sizeof(temp));
577        update_header(&pkts[i],512);      /* update checksums etc */
578        /* change template for new pkt */
579        ip+=1;
580        if(ip>254) {(ip=START_SRC_IP&0xff); port+=1; }
581        temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip);
582        temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port);
583        temp.udp[1] = htonl(temp.udp[1]);
584      
585   }
586   n_pkt=np;
588 #endif
590 void build_table(Trie * p_trie)
592 int i;
593 int sport=NEW_START_SRC_PORT; 
594 HEAD_T temp,temp2;
595 KEY_T key;
597 memcpy(&temp,&testPkt[14],sizeof(temp));
599  //insert entry into trie
600 key.src_ip = temp.ip[3];
601 key.dst_ip = temp.ip[4];
602 key.src_port= (temp.udp[0]&0xffff0000)>>16;
603 key.dst_port= (temp.udp[0]&0x0000ffff);
604 trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[0]); //asociate with nat entry 0
606 //build nat table
607 for(i=0;i<100;i++)
609    memcpy(&temp2,&testPkt[14],sizeof(temp));
610    temp2.udp[0] = (temp2.udp[0] & 0xffff0000) |  sport;
611    memcpy(&nat[i], &temp2, sizeof(temp2));
612    sport+= 1;
616 //===========stub transmitter==================
617 void send_pkt(Ti_Pkt *pkt, int len)
619 //just free pkt.  Don't send
620 Pktlib_freePacket((Ti_Pkt*)pkt);
621         return;
624 //==========stub slow path============
625 void slow_path(Ti_Pkt *pkt, int len)
627 // debug: check descriptor for validity by verifying that desciptor link field is null as expected\n");
628          {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}
629 //just free pkt
630 Pktlib_freePacket((Ti_Pkt*)pkt);
631         return;
633 /* check header */
634 struct LastPktInfo
636 int iface;
637 int ipcsum;
638 int l4csum;
639 } ;
640 static struct LastPktInfo lpInfo;
642 int check_header(HEAD_T * p_head, PKTIO_METADATA_T * p_meta)
644 if (NWAL_RX_FLAG1_META_DATA_VALID & p_meta->u.rx_meta->rxFlag1)
646 lpInfo.iface = ((unsigned int)p_meta->u.rx_meta->appId) &0xff; //last byte is interface num
647 lpInfo.ipcsum =(p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_MASK )== NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_ACK ? 1 : 0;
648 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; 
649 if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC)
651    stats.sec_rx++;
653 if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC_POLICY)
655    stats.secp_rx++;
658 if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_CLASS)
660   int c= ((unsigned int)p_meta->u.rx_meta->appId >>8)&0xffff;
661   if (c==0)  stats.n_class0_rx +=1;
662   else if (c==1) stats.n_class1_rx +=1;
663   else if (c==2) stats.n_class2_rx +=1;
664   else printf("**NET_TEST RX -unknown class: %x\n",  p_meta->u.rx_meta->appId);
668  return 1;
671 #define PKT_LEN 1400
672 void test_alloc_free(int n)
674 int i;
675 Ti_Pkt * b;
677 for(i=0;i<n;i++)
679   b=Pktlib_allocPacket(OurHeap,PKT_LEN);
680   Pktlib_freePacket(b);
684 //measurement test points
685 unsigned int vv1;
686 unsigned int vv2;
687 unsigned int vv3;
688 unsigned int vv4;
689 unsigned int vv5;
690 unsigned int vv6;
691 //these are updated by pktio.
692 #ifdef PKTIO_GET_BENCHMARK
693 extern unsigned int vv7p;
694 extern unsigned int vv8p;
695 extern unsigned int vv9p;
696 extern unsigned int vv10p;
697 extern unsigned int vv11p;
698 extern unsigned int vv12p;
700 extern unsigned int vv13p;  //rcv path
701 extern unsigned int vv14p;
702 extern unsigned int vv15p;
703 #endif
705 unsigned int vv11;
707 extern unsigned int nwal_prof1,nwal_prof2,nwal_prof3,nwal_prof4,nwal_prof5,nwal_prof6;
709 //#define REASSEMBLE_BENCH
710 #ifdef REASSEMBLE_BENCH
711 #include <ti/drv/pa/example/reassemLib/reassemLib.h>
712 /*--------------reassembly benchmark--------------------------------*/
713 void our_reassemble_bench(int nfrags)
715 paIPReassemblyConfig_t Config={5,128,10000 };
716 int i,j;
717 int len;
718 Ti_Pkt tip;
719 char *buffer;
720 unsigned long v1;
721 unsigned long v2;
722 unsigned long sum1=0;
723 unsigned long sum2=0;
724 paEx_reassemLibInit(&Config);
725 for(j=0;j<200/nfrags;j++)
727   for(i=0;i<nfrags;i++)
728   {
729     short temp;
730     tip=Pktlib_allocPacket(OurHeap,PKT_LEN);
731     Pktlib_getDataBuffer(tip,(uint8_t**)&buffer,&len);
732     memcpy(&buffer[0],&testPkt[14],20); //IP header
733     if (i < (nfrags-1)) buffer[6] = 0x20;
734     temp = i*40; 
735     buffer[6]|= (temp&0x1f00)>>8;
736     buffer[7]= (temp&0xff);
737     temp = 20+40*8; 
738     buffer[2]= (temp&0xff00)>>8;
739     buffer[3]= (temp&0xff);
740     Pktlib_setPacketLen(tip, temp);
741     v1= netapi_timing_stop();
742     paEx_reassemLibProc(tip, 0xffff);
743     v2= netapi_timing_stop();
744     sum1+= v2-v1;
745   }
746   sum2 += v2-v1;
748 printf("reasssembly test:  %d trials, %d frags/pkt  %d cycles/frag %d cycles/last frag\n",j,nfrags, sum1/(j*nfrags), sum2/(j));
750 #endif
752 /*--------------basic pktio send/recv benchmark----------------------*/
753 unsigned int timings[10];
754 void our_pktio_bench(int ntrials)
756 int i;
757 #define NBATCH 8
758 Ti_Pkt tip;
759 unsigned char * pData;
760 int len;
761 int n;
762 int err;
763 int sum =0;
765    Osal_cache_op_measure_reset();
766    for(i=0;i<10;i++) timings[i]=0;
767    printf("calibration loop .. ");
768    for(i=0;i<1000;i++)
769    {
770    vv1= netapi_timing_stop();
771    vv2= netapi_timing_stop();
772    sum+=(vv2-vv1);
773    }
774    printf(" accuracy = +- %d cycles\n", sum/1000);
775    sleep(1);
776   
777 PKTIO_METADATA_T meta[10]={0};
778 //send single, recv single
779 for(i=0;i<ntrials;i++)
781    vv1= netapi_timing_stop();
782    tip=Pktlib_allocPacket(OurHeap,PKT_LEN);
783    vv2= netapi_timing_stop();
784    Pktlib_getDataBuffer(tip,&pData,&len);
785    vv3= netapi_timing_stop();
786    pktio_send(our_chan,tip,&meta[0],&err);
787    vv4= netapi_timing_stop();
788    n=pktio_poll(our_chan,NULL , &err);
789    vv5=   netapi_timing_stop();
790    timings[0]+=(vv6-vv4);
791    timings[1]+=(vv5-vv4);
792    timings[3]+=(vv4-vv3); 
793    timings[5]+=(vv3-vv1);
794    timings[8]+=(vv11-vv6);
796 #ifdef PKTIO_GET_BENCHMARK
797    timings[2]+=(vv7p-vv4);
798    timings[4]+=(vv8p-vv3);
799    timings[6]+=(vv9p-vv8p);
800    timings[7]+=(vv10p-vv7p);
801 #endif
804 #ifdef PKTIO_GET_BENCHMARK
805    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,
806            timings[1]/ntrials, timings[2]/ntrials,timings[3]/ntrials, timings[4]/ntrials,timings[5]/ntrials,
807            timings[6]/ntrials,timings[7]/ntrials, timings[8]/ntrials );
808    {
809        unsigned int ccycles;
810        int n_c_ops;
811        ccycles =Osal_cache_op_measure(&n_c_ops);
812        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);
813    }
814 #endif
817 /*-----------test driver: gen an input pkt------- */
818 //char buffer[sizeof(HEAD_T)+PKT_LEN];
819 Ti_Pkt * get_pkt(int n, unsigned int *p_len, Pktlib_HeapHandle heap2use, int size, unsigned char * buf2cpy, int copy_size)
821    int ind;
822    long long temp;
823    Ti_Pkt * b;
824    char * buffer;
825    unsigned int len;
827   if (pktloopback==0)
828   {
829         if (n>=TX_BURST) return NULL;   //just gen pkts to warm swtich, so that it knows
830                                 //our mac is valid
831   }  
832   b=Pktlib_allocPacket(heap2use,size);
833   if (!b) 
834     {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};
836     //debug - way to validate descriptor
837     {Ti_Pkt* k= Pktlib_getNextPacket(b); 
838          if(k != 0) {printf(" genpkt, nexpkt != NULL");}}
841    //get pointer to buffer area of packet
842    Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len);
843    if (!buffer) 
844     {printf("net_test: get_pkt() heap returned empty buffer %d \n", n); return NULL;};
846 #if 0 
847 if (pktloopback==0)
849    temp = (long long) rand();
850    temp *= PKT_LEN;
851    temp /= RAND_MAX;
852    temp +=2;
853    *p_len = (int) temp; 
854    *p_len = *p_len &0xfffffffe;
855    temp = (long long) rand();
856    temp *= n_pkt;
857    temp /= RAND_MAX;
858    ind = (int) temp;
859    update_header(&pkts[ind],*p_len);
860    //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len);
861     memcpy(&buffer[0], &mac_header[0],14);
862     memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T)); 
864 else
865 #endif
867    //copy test packet into buffer
869     memcpy(&buffer[0], buf2cpy, copy_size);
870     *p_len = copy_size;
872     return b; 
875 static int eof=0;
876 /*--------------------------------------------------------------
877  *----------utility to flip a packet and send 
878  *--------------------back to source----------------------------
879  *                   flag=1 => ipsec
880  *--------------------------------------------------------------*/
881 void flip_and_send_pkt(Ti_Pkt *tip,  unsigned char * p_pkt, int len, int flag)
883 unsigned char mac_temp[6];
884 unsigned char ip_temp[4];
885 unsigned char new_dest_port[2]={0x75,0x30};  // 30000
886 uint16_t blah; 
887 uint16_t i=1;   /* for testing only */
889 uint8_t *p_spi; 
890 netTestSA_t * p_sa_info;
891 uint8_t p_iv[16];
893 Pktlib_setPacketLen(tip,len);
894 //mac
895 memcpy(&mac_temp,&p_pkt[0],6);
896 memcpy(&p_pkt[0],&p_pkt[6],6);
897 memcpy(&p_pkt[6],&mac_temp,6);
898 //memcpy(&p_pkt[0],real_mac_header,6); //for testing to wireshark pc
900 //ip  (outer in case of ipsec)
901 memcpy(&ip_temp, &p_pkt[14+12],4);
902 memcpy(&p_pkt[14+12],&p_pkt[14+12+4],4);
903 memcpy(&p_pkt[14+12+4],&ip_temp,4);
905 //outer checksum to 0
906 if (!flag) memset(&p_pkt[14+10],0,2);
911 //inner ip &udp for ipsec
912 if (flag) 
914     p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]);
915     p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa, (char *)p_spi ,4);
916     if (p_sa_info == NULL)
917     {
918         printf("flip_and_send_pkt(): trie_lookup() failed\n");
919         return;
920     }
921     //just drop non-udp packet
922     if (p_pkt[p_sa_info->tx_payload_info.encOffset+9]!=0x11)
923   
924     {
925         stats.n_new+=1;Pktlib_freePacket(tip); return;
926     }
928 memcpy(&ip_temp, &p_pkt[p_sa_info->tx_payload_info.encOffset+12],4);
929 memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+12],&p_pkt[p_sa_info->tx_payload_info.encOffset+12+4],4);
930 memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+12+4],&ip_temp,4);
932 //udp
933 memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+20+2],&new_dest_port[0],2);
934 memset(&p_pkt[p_sa_info->tx_payload_info.encOffset+20+6],0,2); //checksum
939 if (config.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND)
941     //inner ip checksum : leave alone
942 #if 0
943     blah=test_utilOnesCompChkSum (&p_pkt[14+20+8+16], 10);
944     p_pkt[14+20+8+16+10]= (blah&0xff00)>>8;
945     p_pkt[14+20+8+16+11]= blah&0xff;
946 #endif
948     //tbd udp checksum (leave at 0)
950     //outer ip, set to 0 (we will compute on way out
951     memset(&p_pkt[14+10],0,2);
953 else
955 //#else //inflow, don't touch outer , clear inner 
956 //DALmemset(&p_pkt[14+20+8+16+10],0,2); //inner checksum, we will compute on way out
957 //outer ip checksum : leave alone
959 #if 0
960 blah = test_utilOnesCompChkSum (&p_pkt[14], 10);
961 p_pkt[14+10]= (blah&0xff00)>>8;
962 p_pkt[14+11]= blah&0xff;
963 #endif
967 else
969 memset(&p_pkt[14+20+6],0,2);//0 udp checksum (we will compute on way out
970 memcpy(&p_pkt[14+20+2],&new_dest_port[0],2);
973 //IPSEC case, 
974 if (flag)
976         if (config.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND)
977  //send to crypto for encryption
978 //12 byte auth tag
979         {
980            PKTIO_METADATA_T meta = {PKTIO_META_SB_TX,{0},0};
981            int err;
982            nwalDmTxPayloadInfo_t meta_tx={0};
983            meta.sa_handle=p_sa_info->tx_data_mode_handle;  //use TX SA context
985 #if 0
986            meta_tx.ploadLen = len;
988            meta_tx.encOffset =p_sa_info->tx_payload_info.encOffset;
989            
990            meta_tx.authOffset =netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN;
992            //meta_tx.encSize=len - 14- 20-8-16-12;
993            meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -netTest_ICV_LEN;
994            
995            //meta_tx.authSize= len -14-20-12;
996            meta_tx.authSize = len - meta_tx.authOffset - netTest_ICV_LEN;
997            //meta_tx.encIvSize=16;
998            meta_tx.encIvSize = p_sa_info->tx_payload_info.encIvSize;
999            //meta_tx.pEncIV= &p_pkt[14+20+8];  //just use same IV..
1000 #endif
1001             memcpy(&meta_tx, &(p_sa_info->tx_payload_info), sizeof(nwalDmTxPayloadInfo_t));
1003            meta_tx.ploadLen = len;
1004            meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -netTest_ICV_LEN;
1005            meta_tx.authSize = len - meta_tx.authOffset - netTest_ICV_LEN;
1007            meta_tx.encIvSize = p_sa_info->tx_payload_info.encIvSize;
1008 #if 0
1009             printf("flip_and_send_pkt(): encOffset %d\n", meta_tx.encOffset);
1010             printf("flip_and_send_pkt():authOffset %d\n", meta_tx.authOffset);
1011             printf("flip_and_send_pkt(): encSize %d\n", meta_tx.encSize);
1012             printf("flip_and_send_pkt(): authSize %d\n", meta_tx.authSize);
1013             printf("flip_and_send_pkt(): encIvSize %d\n", meta_tx.encIvSize);
1014 #endif
1016         if (p_sa_info->cipherMode ==  NWAL_SA_EALG_AES_CTR)
1017         {
1018            memcpy(&p_iv[0], &ourEncrKey[16], 4);
1019            memcpy(&p_iv[4], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
1020             p_iv[12] = 0;
1021             p_iv[13] = 0;
1022             p_iv[14] = 0;
1023             p_iv[15] = 1;
1024            meta_tx.pEncIV = &p_iv[0];
1025          }
1026         else if (p_sa_info->cipherMode ==  NWAL_SA_EALG_NULL)
1027         {
1028             meta_tx.pEncIV = NULL;
1029         }
1030         else
1031         {
1032             meta_tx.pEncIV = &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN ];
1033         }
1034            meta_tx.authIvSize=0;
1035            meta_tx.pAuthIV=NULL;
1036            meta_tx.aadSize=0;
1037            meta_tx.pAad=NULL;
1038            /* post it to netcp sb tx channel*/
1039            meta_tx.appCtxId = netapi_timing_start();
1040            meta.u.tx_sb_meta=&meta_tx;
1041            pktio_send(netcp_sb_tx_chan,tip,&meta,&err);
1042        }
1043 else
1044  {
1045   //inflow tx
1046   //send pkt directly, asking for IP and UDP checksum offloads AND IPSEC to be applied
1047            PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};
1048            int err;
1049            nwalTxPktInfo_t meta_tx={0};
1050 #define USE_COPY
1051 #ifdef USE_COPY
1052 //debug:  see if re-using RX descriptor for TX is causing our SA lockup
1054   int new_len=0;
1055   Ti_Pkt new_tip =  get_pkt(0, &new_len, specialLarge , len+10 , &p_pkt[0]   , len);
1056   if (!new_tip)
1057   {
1058      printf("net_test> new_tip NULL\n");
1059   }
1060   else
1061   {
1062     Pktlib_setPacketLen(new_tip,new_len);
1063     Pktlib_freePacket(tip);
1064     tip=new_tip;  
1065     Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&new_len);  //reset p_pkt to point to new buffer as its used below
1066     Cppi_setTimeStamp (Cppi_DescType_HOST, (Cppi_Desc *) tip,stats.sec_tx); 
1067   }
1069 if (len <1500)  
1071   eof+=1;
1073 #endif
1074            meta.sa_handle=p_sa_info->tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied
1075            //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 );
1076            meta_tx.txFlag1 = p_sa_info->tx_pkt_info.txFlag1;
1077            meta_tx.enetPort=0;
1078            //meta_tx.saOffBytes=14+20;  
1079            meta_tx.saOffBytes=  p_sa_info->tx_pkt_info.saOffBytes;
1080            meta_tx.saPayloadLen=len-14-20;   //don't include tag, mac and outer header
1081            //meta_tx.startOffset = 0;
1082            meta_tx.startOffset = p_sa_info->tx_pkt_info.startOffset;
1083            //meta_tx.ipOffBytes = 14+20+8+16;   //to inner header
1084            meta_tx.ipOffBytes =p_sa_info->tx_payload_info.encOffset; 
1085            //meta_tx.l4OffBytes = 14+20+8+16+20; //to L4
1086            meta_tx.l4OffBytes = p_sa_info->tx_pkt_info.l4OffBytes;
1087            meta_tx.l4HdrLen = p_sa_info->tx_pkt_info.l4HdrLen;
1088            meta_tx.ploadLen = (unsigned) ((p_pkt[meta_tx.l4OffBytes+4]<<8)|p_pkt[meta_tx.l4OffBytes+4+1]) -8 ;
1089            meta_tx.pseudoHdrChecksum =
1090              test_utilGetIpv4PsudoChkSum(&p_pkt[meta_tx.ipOffBytes],8+ meta_tx.ploadLen);
1092            /* post it to netcp tx channel*/
1093            meta.u.tx_meta=&meta_tx;
1094            if (stats.sec_tx<20) dump_descr((long *) tip, stats.sec_tx);
1095            pktio_send(netcp_tx_chan,tip,&meta,&err);
1096            stats.tx +=1;
1097            stats.sec_tx +=1;
1098      }
1100 else  //non ipsec send pkt directly, asking for IP and UDP checksum ofload
1102            PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
1103            int err;
1104            nwalTxPktInfo_t meta_tx2={0};
1105            meta2.sa_handle=nwal_HANDLE_INVALID;
1106            meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
1107            meta_tx2.startOffset = 0;
1108            meta_tx2.ipOffBytes = 14;
1109            meta_tx2.l4OffBytes = 14+20;
1110            meta_tx2.l4HdrLen = 8;
1111            meta_tx2.ploadLen = (unsigned) ((p_pkt[14+20+4]<<8)|p_pkt[14+20+4+1]) -8 ;
1112            meta_tx2.pseudoHdrChecksum =
1113              test_utilGetIpv4PsudoChkSum(&p_pkt[14],8+ meta_tx2.ploadLen);
1115            /* post it to netcp tx channel*/
1116            meta2.u.tx_meta=&meta_tx2;
1117            pktio_send(netcp_tx_chan,tip,&meta2,&err);
1118            stats.tx +=1;
1125 /***************************************
1126  benchmark receive handler
1127 ****************************************/
1128 void recv_cb_bench(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
1129                          PKTIO_METADATA_T meta[], int n_pkts,
1130                          uint64_t ts )
1132    int i;
1133    vv6=   netapi_timing_stop();
1134    for (i=0;i<n_pkts; i++) 
1135    {
1136      Pktlib_freePacket(p_recv[i]);
1137    }
1138    vv11 = netapi_timing_stop();
1141 /****************************************************************************************/
1142 /******************SB Accelerator Callback PKT RECEIVE HANDLER *************************/
1143 /******************  Handles Decrypt and Encrypt operation callbacks ******************/
1144 /******************************************************************************************/
1145 void recv_sb_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
1146                          PKTIO_METADATA_T meta[], int n_pkts,
1147                          uint64_t ts )
1149 int i;
1150 int len;
1151 int p;
1152 HEAD_T * p_res;
1153 Ti_Pkt * tip;
1154 unsigned int templen;
1155 int err;
1156 KEY_T key;
1157 char * p_pkt;
1158 HEAD_T * p_head;
1159 HEAD_T temp_head;
1160 int tag_cmp=0;
1161 unsigned int hash[3];
1162 uint8_t *p_spi;
1163 netTestSA_t *p_sa_info;
1165 //nwal_AppId time;
1166 unsigned long time, delta_time;
1167  /* loop over received pkts */
1168    for(i=0;i<n_pkts;i++)
1169    {
1170         tip = p_recv[i];
1171         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
1172         len = Pktlib_getPacketLen(tip);//real length
1175          p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]);
1176         p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa, (char *)p_spi ,4);
1177         if (p_sa_info == NULL)
1178         {
1179             printf("recv_sb_cb(): trie_lookup failed\n");
1180             continue;
1181         }
1184         //is this a decrypt (rx_tunnel) complete
1185         if ((int)meta[i].u.rx_sb_meta->appId == p_sa_info->rx_tunnel)
1186         {
1187            
1188             time = netapi_timing_start();
1189            delta_time = time -(unsigned long) meta[i].u.rx_sb_meta->appCtxId;
1190             stats.total_decrypt_time += delta_time;
1191             stats.sb_rx+=1;
1192            //copy hash out of meta data (for some reason it needs endian conversion)
1193            hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
1194            hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
1195            hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]);
1197            if(stats.sb_rx<=16)
1198            {
1199              char *tp = (char *) &hash[0];
1200              //dump_header((long*)p_pkt, stats.sb_rx, (int)meta[i].u.rx_sb_meta->appId,0);
1201 #if 0
1202              printf("tag in pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n",
1203                       p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],
1204                       p_pkt[len-7],p_pkt[len-6],
1205                       p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]);
1206              printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n",
1207                        tp[0],tp[1],tp[2],tp[3],tp[4],tp[5],
1208                        tp[6],tp[7],tp[8],tp[9],tp[10],tp[11]);
1209 #endif
1210            }
1211            //check tag 
1212            tag_cmp = memcmp(&p_pkt[len-12],(char*) &hash[0],12); //todo, really use meta->authTagLen
1213            stats.n_auth_ok += !(tag_cmp);
1214            
1215             flip_and_send_pkt(tip, p_pkt, len,1);  //flip packet to echo back and send
1216         }
1217         //this is an encrypt (tx tunnel) complete
1218         else if((int)meta[i].u.rx_sb_meta->appId== p_sa_info->tx_tunnel )
1219         {
1220            hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
1221            hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
1222            hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]);
1223            stats.sb_tx+=1;
1224            if(stats.sb_tx<=16)
1225            {
1226              char *tp1 = (char *) &hash[0];
1227              //dump_header((long*)p_pkt, stats.sb_tx, (int)meta[i].u.rx_sb_meta->appId,0);
1228 #if 0
1229              printf("tag in original rx pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n",
1230                       p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],
1231                       p_pkt[len-7],p_pkt[len-6],
1232                       p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]);
1234              printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n",
1235                        tp1[0],tp1[1],tp1[2],tp1[3],tp1[4],tp1[5],
1236                        tp1[6],tp1[7],tp1[8],tp1[9],tp1[10],tp1[11]);
1237 #endif
1238            }
1239            //put the computed tag in the packet
1240            memcpy(&p_pkt[len-12],(char*)&hash[0],12); //todo, really use meta->authTagLen
1241            {
1242            PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
1243            nwalTxPktInfo_t meta_tx={0};
1244            // now send directly 
1245            meta2.sa_handle=nwal_HANDLE_INVALID;
1246            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
1247            meta_tx.startOffset = 0;
1248            meta_tx.ipOffBytes = netTest_MAC_HEADER_LEN;
1249            //not used
1250            meta_tx.l4OffBytes = 0;
1251            meta_tx.l4HdrLen = 0;
1252            meta_tx.ploadLen = 0;
1253             time = netapi_timing_start();
1254             delta_time = time -(unsigned long) meta[i].u.rx_sb_meta->appCtxId;
1255            stats.total_encrypt_time += delta_time;
1256         
1258            /* post it to netcp tx channel*/
1259            meta2.u.tx_meta=&meta_tx;
1260            pktio_send(netcp_tx_chan,tip,&meta2,&err);
1261            stats.tx +=1;
1262            }
1263         }
1264         else printf("netapi recv_sb_cb: unknown appiD %x \n",meta[i].u.rx_sb_meta->appId );
1265     }
1268 /******************************************************/
1269 /******************PKT RECEIVE HANDLER *************************/
1270 /******************************************************/
1271 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
1272                          PKTIO_METADATA_T meta[], int n_pkts,
1273                          uint64_t ts )
1275 int i;
1276 int len;
1277 int p;
1278 HEAD_T * p_res;
1279 Ti_Pkt * tip;
1280 unsigned int templen;
1281 int err;
1282 KEY_T key;
1283 char * p_pkt;
1284 HEAD_T * p_head;
1285 HEAD_T temp_head;
1286 netTestSA_t *p_sa_info;
1287 uint8_t *p_spi;
1288 uint8_t p_iv[16];
1290     p_head=&temp_head;
1292     //debug
1293 #if 0
1294     if (n_pkts != TX_BURST) {
1295       printf("recv_cb, txsofar=%d rxsofar=%d  np = %d, NOT %d\n", 
1296              stats.itx, stats.rx, n_pkts,TX_BURST);
1297       our_stats_cb(netapi_handle,NULL);
1298     }
1299 #endif
1300     //test_alloc_free(7);
1301     //printf("recv start\n");
1303     /* loop over received pkts */
1304     for(i=0;i<n_pkts;i++)
1305    {
1306         tip = p_recv[i];
1307         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
1308         len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
1309         Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
1310         Pktlib_setPacketLen(tip,len);
1312         //debug: validate descriptor */
1313         if(Pktlib_getNextPacket(tip) != 0) 
1314         {
1315             printf(" rcv_cb, nexpkt != NULL");
1316         }
1317         //debug printf("recv pkt, len=%d %d\n", len, templen);
1318         stats.rx+=1;
1320 #ifdef DEBUG_DESC
1321         if (stats.rx<16)
1322         {
1323             printf(">rx dmp.."); 
1324             dump_descr((long *) tip, stats.rx);
1325         }
1326         else if (stats.rx>99) 
1327         {
1328             printf(">rx dmp.."); 
1329             dump_descr((long *) tip,stats.rx);
1330         }
1331 #endif
1332 #if 0
1333         if(stats.rx<=16)
1334         {
1335             dump_header((long*)p_pkt, stats.rx, (int)meta[i].u.rx_meta->appId,meta[i].u.rx_meta->rxFlag1);
1336         }
1337 #endif
1338         /* check header */
1339         memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
1341         if ((p_head->ip[2]&0x0000ff00)==0x00003200)
1342         {
1343             if (!check_header(p_head,&meta[i]))
1344             {
1345                 stats.n_bad+=1;Pktlib_freePacket(tip); 
1346                 continue;
1347             }
1352             //process IP SEC PACKET
1353         if (config.ipsec_mode_rx == IPSEC_MODE_RX_SIDEBAND)
1354         {
1355             p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]);
1356             p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa, (char *)p_spi ,4);
1357             if (p_sa_info == NULL)
1358             {
1359                 printf("recv_cb(): trie_lookup() failed\n");
1360                 continue;
1361             }
1362            //ship to crypto for decrypt!!
1363            //12 byte auth tag
1364             PKTIO_METADATA_T meta2 = {PKTIO_META_SB_TX,{0},0};
1365            nwalDmTxPayloadInfo_t meta_tx={0};
1366            meta2.sa_handle=p_sa_info->rx_data_mode_handle;
1368            memcpy(&meta_tx, &(p_sa_info->tx_payload_info), sizeof(nwalDmTxPayloadInfo_t));
1370            meta_tx.ploadLen = len;
1371            meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -netTest_ICV_LEN;
1372            meta_tx.authSize = len - meta_tx.authOffset - netTest_ICV_LEN;
1374            meta_tx.encIvSize = p_sa_info->tx_payload_info.encIvSize;
1375 #if 0
1376             printf("recv_cb(): encOffset %d\n", meta_tx.encOffset);
1377             printf("recv_cb():authOffset %d\n", meta_tx.authOffset);
1378             printf("recv_cb(): encSize %d\n", meta_tx.encSize);
1379             printf("recv_cb(): authSize %d\n", meta_tx.authSize);
1380             printf("recv_cb(): encIvSize %d\n", meta_tx.encIvSize);
1381 #endif
1383             if (p_sa_info->cipherMode ==  NWAL_SA_EALG_AES_CTR)
1384             {
1385                 memcpy(&p_iv[0], &ourEncrKey[16], 4);
1386                 memcpy(&p_iv[4], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
1387                 p_iv[12] = 0;
1388                 p_iv[13] = 0;
1389                 p_iv[14] = 0;
1390                 p_iv[15] = 1;
1391                  meta_tx.pEncIV = &p_iv[0];
1392             }
1393             else if (p_sa_info->cipherMode ==  NWAL_SA_EALG_NULL)
1394             {
1395                 meta_tx.pEncIV = NULL;
1396             }
1397             else
1398             {
1399                 meta_tx.pEncIV = &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN ];
1400             }
1401             meta_tx.appCtxId = netapi_timing_start();
1402             //printf("recv_cb appCtxId: %lu\n", meta_tx.appCtxId);
1404            /* post it to netcp sb tx channel*/
1405            meta2.u.tx_sb_meta=&meta_tx;
1406            pktio_send(netcp_sb_tx_chan,tip,&meta2,&err);
1407            continue;
1408         }
1409         else 
1410             //inflow mode.  flip and send
1411             flip_and_send_pkt(tip,p_pkt,len,1);
1412     }
1413     else if ((p_head->ip[2]&0x0000ff00)!=0x00001100)
1414     {
1415         stats.n_new+=1;Pktlib_freePacket(tip); continue;
1416     }
1417     else  //non ipsec
1418     {
1419         if (!check_header(p_head,&meta[i])) { 
1420                 stats.n_bad+=1;Pktlib_freePacket(tip); 
1421         continue;
1422         }
1424 #if 0
1425         /* lookup flow */
1426         key.src_ip = p_head->ip[3];
1427         key.dst_ip = p_head->ip[4];
1428         key.src_port= (p_head->udp[0]&0xffff0000)>>16;
1429         key.dst_port= (p_head->udp[0]&0x0000ffff);
1430         p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key));
1431         if (!p_res) { stats.n_new+=1;  slow_path(tip, len); continue;}
1433         /* copy header */
1434         memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T));
1436         memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));
1437         /* update_mac(&p_pkt[0]);  */
1439         /* 'simulate' send pkt */
1440         send_pkt(tip,len);
1441 #endif
1442              //just flip and send
1443             flip_and_send_pkt(tip,p_pkt,len,0);
1444         }
1445     }
1446     //printf("recv done\n");
1449 //timer callback 
1450 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
1451         int n_fired,     //# timers fired
1452         NETAPI_TIMER_LIST_T fired_list,
1453         uint64_t currentTime)
1455 int i;
1456 NETAPI_TIMER_T tx;
1457 int cookie;
1458 int err;
1459 unsigned long long et;
1460 //DEBUGprintf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);
1461 tx = netapi_TimerGetFirst(fired_list);
1462 for(i=0;i<n_fired;i++)
1464   cookie = (int) netapi_TimerGetCookie(tx);
1465   et =  netapi_TimerGetTs(tx); //debug
1466   //DEBUGprintf("   timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);
1467   if (cookie ==1)
1468   {  
1469      stats.n_t1+=1;
1470      t1 = netapi_TimerGroupStartTimer(
1471         th,
1472         (void *) 1,
1473         100LL,  //timer group tics
1474         &err);
1475   }
1476   else if (cookie ==2)
1477   {
1478       stats.n_t2+=1;
1479       t2 = netapi_TimerGroupStartTimer(
1480         th,
1481         (void *) 2,
1482         200LL,  //timer group ticks
1483         &err);
1484   }
1485   else
1486   {
1487     stats.n_t3+=1;
1488     t3 = netapi_TimerGroupStartTimer(
1489         th,
1490         (void *) 3,
1491         300LL,  //timer group ticks
1492         &err);
1493     //cancel 1 and restart 1
1494    netapi_TimerGroupCancel(th,t1,&err);
1495    t1 = netapi_TimerGroupStartTimer(
1496         th,
1497         (void *) 1,
1498         100LL,  //timer group ticks
1499         &err);
1500  }
1501   tx = netapi_TimerGetNext(fired_list,tx); 
1505 void print_ipsec_stats(Sa_IpsecStats_t     *p_saIpsecStats, nwal_saAALG auth, nwal_saEALG cipher)
1507 #if 0
1508     if(retVal != nwal_OK)
1509     {
1510         System_printf("CORE: %d Error getting IP Sec Stats: Ret Status: %d \n",
1511                        retVal);
1512         return(nwal_FALSE);
1513     }
1514     if((p_saIpsecStats->pktEncHi) ||(p_saIpsecStats->pktEncLo))
1515     {
1516         printf("------------- IPSec TX (Encryption Channel) Stats BEGIN --\n");
1517     }
1518     else
1519     {
1520         printf("------------- IPSec RX (Decryption Channel) Stats BEGIN --\n");
1521     }
1522 #endif
1523     printf("\nAutentication mode: %d, Encryption Mode: %d\n", auth, cipher);
1524     printf("IPSec replayOld:0x%x,replayDup:0x%x,authFail:0x%x \n",
1525                    p_saIpsecStats->replayOld,p_saIpsecStats->replayDup,p_saIpsecStats->authFail);
1526     printf("IPSec txESN:0x%x,rxESN:0x%x,pktEncHi:0x%x,pktEncLo:0x%x,pktDecHi:0x%x,pktDecLo:0x%x \n",
1527                    p_saIpsecStats->txESN,p_saIpsecStats->rxESN,p_saIpsecStats->pktEncHi,
1528                    p_saIpsecStats->pktEncLo,p_saIpsecStats->pktDecHi,p_saIpsecStats->pktDecLo);
1531 void print_datamode_stats(Sa_DataModeStats_t     *p_saDataModeStats, nwal_saAALG auth, nwal_saEALG cipher)
1534     printf("\nAutentication mode: %d, Encryption Mode: %d\n", auth, cipher);
1535     printf(" Packets processedHi: 0x%x, Packets processed Lo:0x%x\n",
1536             p_saDataModeStats->pktHi, p_saDataModeStats->pktLo);
1542 static int np2process = NP;
1543 /******************************************************
1544  * stats callback
1545  *******************************************************/
1546 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)
1548 uint32_t numFreeDataPackets;
1549 uint32_t            numZeroBufferPackets;
1550 uint32_t            numPacketsinGarbage;
1551 Pktlib_HeapStats    pktLibHeapStats;
1552 int i;
1553 unsigned long long bcpp;
1554 unsigned long long bcpp_noc;
1555 unsigned long long bcpp_app;
1556 unsigned long long bcpp_tx;
1557 unsigned long long npL;
1558 unsigned long long cyclesL;
1559 unsigned long long ccyclesL; //cache cycles
1560 NETAPI_SA_STATS_T netapi_sa_stats;
1562 printf(">*****stats @ %lld\n", netapi_getTimestamp());
1563 //printf("netcp_tx_handle check %x\n", netcp_tx_chan->back);
1564 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",
1565          stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new, 
1566          stats.n_class0_rx, stats.n_class1_rx, 
1567          stats.n_class2_rx, stats.sec_rx, stats.secp_rx, stats.sb_rx, stats.sb_tx, stats.n_auth_ok,
1568          stats.sec_tx);
1570 if (stats.rx && stats.tx)
1571     printf("decrypt time per packet(avg): %lu, encrypt  time per packet(avg): %lu\n", 
1572     (unsigned long) stats.total_decrypt_time/stats.rx, (unsigned long) stats.total_encrypt_time/stats.tx);
1573 netapi_sched_get_stats(&npL,&cyclesL,&ccyclesL);
1574 if (npL && stats.rx) {
1575    bcpp = cyclesL/npL; 
1576    bcpp_noc = (cyclesL-ccyclesL)/npL; 
1577    bcpp_app = (stats.app_cycles-stats.tx_cache_cycles)/stats.rx;
1578
1579 else {bcpp = bcpp_noc=bcpp_app=0L;}
1580 if (stats.tx)
1582     bcpp_tx = (stats.send_cycles-stats.tx_cache_cycles)/stats.tx;
1583 }else {bcpp_tx = 0L;}
1584 printf(">         ++ busy cycles pp=%lld (%lld wo cache ops) (app+tx= %lld) (tx= %lld) ++\n",
1585          bcpp,bcpp_noc,bcpp_app, bcpp_tx);
1586 if(pPaStats)
1588        printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);
1589        printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);
1590        printf("C1 number IPv6 packets:        %d\n", pPaStats->classify1.nIpv6Packets);
1591        printf("C1 number Custom packets:        %d\n", pPaStats->classify1.nCustomPackets);
1592        printf("C1 number SRIO packets:        %d\n", pPaStats->classify1.nSrioPackets);
1593        printf("C1 number LLC/SNAP Fail packets:        %d\n", pPaStats->classify1.nLlcSnapFail);
1594        printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);
1595        printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);
1596        printf("C1 number IP Fragmented packets: %d\n", pPaStats->classify1.nIpFrag);
1597        printf("C1 number IP Depth Overflow: %d\n", pPaStats->classify1.nIpDepthOverflow);
1598        printf("C1 number VLAN Depth Overflow: %d\n", pPaStats->classify1.nVlanDepthOverflow);
1599        printf("C1 number GRE Depth Overflow: %d\n", pPaStats->classify1.nGreDepthOverflow);
1600        printf("C1 number MPLS Packets: %d\n", pPaStats->classify1.nMplsPackets);
1601        printf ("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);
1602        printf("C1 number of Invalid IPv6 Opt:  %d\n", pPaStats->classify1.nInvalidIPv6Opt);
1603        printf("C1 number of TX IP Fragments:  %d\n", pPaStats->classify1.nTxIpFrag);
1604        printf ("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);
1605        printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);
1606        printf ("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);
1607        printf ("C1 number of system fails:      %d\n",pPaStats->classify1.nSystemFail);
1608        printf ("C2 number Packets  :           %d\n",pPaStats->classify2.nPackets);
1609        printf ("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);
1610        printf ("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);
1611        printf ("C2 number Custom       :      %d\n",pPaStats->classify2.nCustom);
1612        printf ("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);
1613        printf ("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);
1614        printf ("C2 number Modify Stats Cmd Fail :      %d\n\n",pPaStats->modify.nCommandFail);
1616 Pktlib_getHeapStats(OurHeap, &pktLibHeapStats);
1617 printf("main heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
1618                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
1619 printf("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
1620                         pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
1621                         pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
1623 Pktlib_getHeapStats(specialSmall, &pktLibHeapStats);
1624 printf("specialSmall heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
1625                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
1626 printf("                       >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
1627                                 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
1628                                 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
1631 Pktlib_getHeapStats(specialLarge, &pktLibHeapStats);
1632 printf("specialLarge heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
1633                                 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
1634 printf("                       >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", 
1635                                 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
1636                                 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
1639 #if 0
1640 printf("pa2sa descriptor area dump\n");
1641 for(i=0;i<TUNE_NETAPI_CONFIG_MAX_PA_TO_SA_DESC;i++)
1643    extern long * pa2sa_descr_base;
1644    long * tip= &pa2sa_descr_base[32*i]; 
1645    dump_descr(tip, i);
1647 printf("sa2pa descriptor area dump\n");
1648 for(i=0;i<TUNE_NETAPI_CONFIG_MAX_SA_TO_PA_DESC;i++)
1650    extern long * sa2pa_descr_base;
1651    long * tip= &sa2pa_descr_base[32*i]; 
1652    dump_descr(tip, i);
1654 #endif
1655 //debug = dump timer polling stats
1656 //dump_poll_stats();
1658 #ifndef EXPERIMENTAL
1659     for (i = 0; i < MAX_SEC_INDEX; i++)
1660 #else
1661     for (i=0; i < 1;i++)
1662 #endif
1663     {
1664         if (config.ipsec_mode_rx == IPSEC_MODE_RX_INFLOW)
1665         {
1666             memset(&netapi_sa_stats, 0, sizeof(netapi_sa_stats));
1667             netapi_getSaStats(netapi_handle, sa_info[i].rx_tunnel, &netapi_sa_stats);
1668             if (netapi_sa_stats.mode_active & NETAPI_INFLOW_MODE_ACTIVE)
1669                 print_ipsec_stats(&(netapi_sa_stats.saIpsecStats), rx_sa[i].authMode, rx_sa[i].cipherMode);
1670         }
1671 #if 0
1672         else
1673         {
1674             memset(&netapi_sa_stats, 0, sizeof(netapi_sa_stats));
1675             netapi_getSaStats(netapi_handle, sa_info[i].rx_tunnel, &netapi_sa_stats);
1676              if (netapi_sa_stats.mode_active & NETAPI_SIDEBAND_MODE_ACTIVE)
1677             print_datamode_stats(&(netapi_sa_stats.dataModeStats),rx_sa[i].authMode, rx_sa[i].cipherMode);
1678         }
1679 #endif
1681         if (config.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
1682         {
1683             memset(&netapi_sa_stats, 0, sizeof(netapi_sa_stats));
1684             netapi_getSaStats(netapi_handle, sa_info[i].tx_tunnel, &netapi_sa_stats);
1685              if (netapi_sa_stats.mode_active & NETAPI_INFLOW_MODE_ACTIVE)
1686                 print_ipsec_stats(&(netapi_sa_stats.saIpsecStats), tx_sa[i].authMode, tx_sa[i].cipherMode);
1687         }
1688 #if 0
1689         else
1690         {
1691             memset(&netapi_sa_stats, 0, sizeof(netapi_sa_stats));
1692             netapi_getSaStats(netapi_handle, sa_info[i].tx_tunnel, &netapi_sa_stats);
1693             if (netapi_sa_stats.mode_active & NETAPI_SIDEBAND_MODE_ACTIVE)
1694                 print_datamode_stats(&(netapi_sa_stats.dataModeStats),tx_sa[i].authMode, tx_sa[i].cipherMode);
1695         }
1696  #endif
1697         
1698     }
1701 //******************************************************
1702 //use scheduling housekeeping callback to generate pkts
1703 //******************************************************
1704 static int done_burst=0;
1705 void house(NETAPI_SCHED_HANDLE_T * s)
1707 Ti_Pkt * tip;
1708 unsigned int len;
1709 nwalTxPktInfo_t meta_tx = {0};
1710 PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};
1711 int err;
1712 static int house_pkts_gened=0;
1713 int p;
1714 unsigned char * pIpHdr,* pData;
1715 unsigned int vv1,vv2,vv3;
1716 unsigned int sum_vv1=0;
1717 unsigned int sum_vv2=0;
1718 unsigned int sum_vv3=0;
1719 unsigned int sum_vv4=0;
1720 unsigned int sum_vv5=0;
1722 unsigned int nwal_flow_vv1,nwal_flow_vv2;
1723 unsigned int nwal_sum_vv1=0;
1724 unsigned int nwal_sum_vv2=0;
1725 unsigned int nwal_sum_vv3=0;
1726 unsigned int nwal_sum_vv4=0;
1727 unsigned int nwal_sum_vv5=0;
1728 unsigned int nwal_sum_vv6=0;
1730 unsigned int nwal_sum_flow_vv1=0;
1731 unsigned int nwal_sum_flow_vv2=0;
1732 unsigned int cache_op_b1;
1733 unsigned int cache_op_b2;
1734 int n_c_ops;
1735 static int first =0;
1736 Cppi_HostDesc*      pPktDesc;
1738 if(done_burst)
1740   house_pkts_gened+=TX_BURST;
1741   printf("net_test> request stats at n=%d \n",house_pkts_gened);
1742   netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err);
1743   if (err!=0) {printf("stats req failed\n");}
1744   if (house_pkts_gened >= np2process+ 100)
1745   {
1746      netapi_schedShutdown(s,NULL,&err);
1747   }
1748   return;
1750 done_burst=1;
1751 Osal_cache_op_measure_reset();
1752 memset(&meta_tx,0,sizeof(meta_tx));
1753 for(p=0;p<TX_BURST;p++) {  
1754 //reguest stats 
1755 if ((house_pkts_gened>0) && (! (house_pkts_gened%1000)) )
1757    printf("net_test> request stats at n=%d \n",house_pkts_gened);
1758    netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err); 
1759    if (err!=0) {printf("stats req failed\n");}
1763   if (house_pkts_gened >= np2process+ 100)
1764   {
1765      //shutdown
1766      netapi_schedShutdown(s,NULL,&err);
1767      continue;
1768   }
1770   else if (house_pkts_gened >= np2process) { house_pkts_gened+=1;  continue;}
1771   
1773 /* manufacture a pkt to transmit */
1774    tip = get_pkt(house_pkts_gened, &len, OurHeap, PKT_LEN,&testPkt[0]  , TEST_PKT_LEN);
1775    if(!tip) { house_pkts_gened +=1; continue; }
1778    /* set the pkt length */
1779    vv1 = netapi_timing_start();
1780    Pktlib_setPacketLen(tip, len);
1782    /* set up meta data */
1783     meta.sa_handle=nwal_HANDLE_INVALID;
1784 //#define BENCH_UDP_SEND
1785 #ifdef BEND_UDP_SEND
1786     meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID);
1787     meta_tx.startOffset = 0;
1788     //GONE in V2 meta_tx.pktLen = len;
1789     meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES;
1790     meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES;
1791     meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN;
1792     //GONE in V2 meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;
1793     meta_tx.ploadLen = TEST_PAYLOAD_LEN;
1795     Pktlib_getDataBuffer(tip,&pData,&len);
1796    if(house_pkts_gened &0x1)
1797    {
1798         memcpy(&pData[6],&config.mac1[0] ,6);
1799    }
1800     pIpHdr = pData + meta_tx.ipOffBytes;
1801     meta_tx.pseudoHdrChecksum =
1802         test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));
1803 #else
1804    Pktlib_getDataBuffer(tip,&pData,&len);
1805    if(house_pkts_gened &0x1)
1806    {
1807         memcpy(&pData[6],&config.mac1[0] ,6);
1808    }
1809     meta_tx.txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID;
1810     meta_tx.startOffset = 0;
1811     meta_tx.ploadLen = TEST_PAYLOAD_LEN;
1812 #endif
1813    /* post it to netcp tx channel*/
1814    meta.u.tx_meta=&meta_tx;
1815 #ifdef DEBUG_DESC
1816    if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened);
1817    else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened);
1818 #endif
1820    if(!first)
1821    {
1822        first++;
1823        nwal_flow_vv1= netapi_timing_stop();
1824        if(nwal_initPSCmdInfo(PKTIO_GET_NWAL_INSTANCE(netcp_tx_chan),
1825                              &meta_tx,
1826                              &flowPSCmdInfo) != nwal_OK)
1827        {
1828            printf("nwal_initPSCmdInfo() ERROR \n");
1829        }
1830        nwal_flow_vv2= netapi_timing_stop();
1831        nwal_sum_flow_vv1 += (nwal_flow_vv1-vv1); 
1832        nwal_sum_flow_vv2 += (nwal_flow_vv2-nwal_flow_vv1); 
1833    }
1834        
1835    cache_op_b1= Osal_cache_op_measure(&n_c_ops);
1836    vv2= netapi_timing_stop();
1837 #ifdef BEND_UDP_SEND
1838    nwal_mCmdSetL4CkSumPort(  tip,
1839                              &flowPSCmdInfo,
1840                              TEST_PKT_UDP_OFFSET_BYTES,
1841                              (TEST_PKT_UDP_HDR_LEN + TEST_PAYLOAD_LEN),
1842                              meta_tx.pseudoHdrChecksum,
1843                              meta_tx.enetPort);
1844 #else
1845    nwal_mCmdSetPort  (tip,
1846                       &flowPSCmdInfo,  //could be NULL
1847                       0);  //port 0 -> switch decides
1849 #endif
1851    pPktDesc = Pktlib_getDescFromPacket(tip);
1852    /* Send the packet out to transmit Q*/
1853    Qmss_queuePushDescSize (flowPSCmdInfo.txQueue, 
1854                         pPktDesc, 
1855                         NWAL_DESC_SIZE);
1856    vv3= netapi_timing_stop();
1857    cache_op_b2= Osal_cache_op_measure(&n_c_ops);
1859    sum_vv1 += (vv2-vv1);
1860    if(!house_pkts_gened)
1861    {
1862        /* first packet. Take out the PS command label creation cost */
1863        sum_vv1 = sum_vv1 - nwal_sum_flow_vv2;
1864    }
1866    sum_vv3 += (vv3-vv2)-(cache_op_b2-cache_op_b1); //sub out cache op cost
1868    // printf("pktio send. full=%d metadata=%d pktio_send=%d\n", vv3-vv1,  vv2-vv1,  vv3-vv2);
1869    
1871    stats.itx +=1;
1872    house_pkts_gened +=1;
1873  }
1875    unsigned int ccycles;
1876    ccycles =Osal_cache_op_measure(&n_c_ops);
1877    if (sum_vv1) 
1878    {
1879       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", 
1880               stats.itx, sum_vv1/stats.itx,  nwal_sum_flow_vv2, sum_vv3/stats.itx, 
1881               n_c_ops, ccycles, n_c_ops? (ccycles/(n_c_ops/2)) : 0);
1882 #if 0
1883       printf("NWAL Profile Cycles: Prof1= %d,Prof2=%d,Prof3=%d,Prof4=%d,Prof5=%d ,Prof6=%d \n",
1884               nwal_sum_vv1/stats.itx,nwal_sum_vv2/stats.itx,nwal_sum_vv3/stats.itx,
1885               nwal_sum_vv4/stats.itx,nwal_sum_vv5/stats.itx,nwal_sum_vv6/stats.itx);
1886   
1887 #endif  
1889       if(stats.itx2)
1890       {
1891           printf("nwal_flowSend Profile Cycles: Prof1= %d,Prof2=%d \n",
1892               nwal_sum_flow_vv1/stats.itx2,nwal_sum_flow_vv2/stats.itx2);
1893       }
1895    }
1899 void  build_sa_db(int i)
1902     if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_SHA1) && (tx_sa[i].cipherMode == NWAL_SA_EALG_AES_CBC))
1903     {
1904         /* static configuration, will not change */
1905         sa_info[i].tx_payload_info.aadSize = 0;
1906         sa_info[i].tx_payload_info.pAad = NULL;
1907         sa_info[i].tx_payload_info.authIvSize = 0;
1908         sa_info[i].tx_payload_info.pAuthIV = NULL;
1909         sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;        /*done: same for all cipher suites */
1910         sa_info[i].tx_payload_info.encIvSize = netTest_AES_CBC_IV_LEN;
1911         sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN +
1912                                                                      netTest_IP_HEADER_LEN +
1913                                                                     netTest_ESP_HEADER_LEN +
1914                                                                     netTest_AES_CBC_IV_LEN;
1916        
1918         /* dynamic configuration, will  be calculated on the fly */
1919         sa_info[i].tx_payload_info.authSize = 0; /* pkt len - mac - ip -icv (12) */
1920         sa_info[i].tx_payload_info.encSize = 0;   /* authSize - esp header size (always 8 bytes) */
1921         sa_info[i].tx_payload_info.ploadLen = 0;  /* will be packet length */
1922         sa_info[i].tx_payload_info.pEncIV = 0;
1923        sa_info[i].tx_payload_info.pPkt = 0;     /* not being referenced in net_test */
1925         sa_info[i].cipherMode = NWAL_SA_EALG_AES_CBC;
1926         sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
1927         sa_info[i].auth_tag_size = netTest_ICV_LEN;  /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
1928 #ifdef EXPERIMENTAL
1929         sa_info[i].iv_len=16;
1930         sa_info[i].bl=16;
1931         sa_info[i].spi = tx_sa[i].spi;
1932         sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
1933         sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
1934 #endif
1935         sa_info[i].tx_pkt_info.enetPort = 0;
1936         sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
1937         sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
1938         sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
1939         sa_info[i].tx_pkt_info.startOffset = 0;
1940         sa_info[i].tx_pkt_info.lpbackPass = 0;
1941         sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
1942         sa_info[i].tx_pkt_info.pPkt = NULL;
1943         sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;
1944         sa_info[i].tx_pkt_info.saPayloadLen = 0;
1945         sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
1946        
1947         sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
1949          trie_insert(p_trie_sa,(char *)&(tx_sa[i].spi),4, (void *) &sa_info[i]); //asociate with tx sa SPI
1950          
1951     }
1952     else if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_SHA2_256) && (tx_sa[i].cipherMode == NWAL_SA_EALG_AES_CTR))
1953     {
1954         printf("inside build_sa_db, index %d\n", i);
1955         /* static configuration, will not change */
1956         sa_info[i].tx_payload_info.aadSize = 0;
1957         sa_info[i].tx_payload_info.pAad = NULL;
1958         sa_info[i].tx_payload_info.authIvSize = 0;
1959         sa_info[i].tx_payload_info.pAuthIV = NULL;
1960         sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;        /*done: same for all cipher suites */
1961         sa_info[i].tx_payload_info.encIvSize = netTest_AES_CTR_IV_CONTEXT_LEN;
1962         sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN +
1963                                                                      netTest_IP_HEADER_LEN +
1964                                                                     netTest_ESP_HEADER_LEN +
1965                                                                     netTest_AES_CTR_IV_PACKET_LEN;
1970         /* dynamic configuration, will  be calculated on the fly */
1971         sa_info[i].tx_payload_info.authSize = 0;
1972         sa_info[i].tx_payload_info.encSize = 0;
1973         sa_info[i].tx_payload_info.ploadLen = 0;
1974         sa_info[i].tx_payload_info.pEncIV = 0;
1975         sa_info[i].tx_payload_info.pPkt = 0;
1977         sa_info[i].cipherMode = NWAL_SA_EALG_AES_CTR;
1978         sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
1979         sa_info[i].auth_tag_size = netTest_ICV_LEN;  /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
1980 #ifdef EXPERIMENTAL
1981         sa_info[i].iv_len=8;
1982         sa_info[i].bl=8;
1983         sa_info[i].spi = tx_sa[i].spi;
1984         sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
1985         sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
1986 #endif
1988         sa_info[i].tx_pkt_info.enetPort = 0;
1989         sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
1990         sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
1991         sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
1992         sa_info[i].tx_pkt_info.startOffset = 0;
1993         sa_info[i].tx_pkt_info.lpbackPass = 0;
1994         sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
1995         sa_info[i].tx_pkt_info.pPkt = NULL;
1996         sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;
1997         sa_info[i].tx_pkt_info.saPayloadLen = 0;
1998         sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
1999        
2000         sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
2002        trie_insert(p_trie_sa,(char *)&(tx_sa[i].spi),4, (void *) &sa_info[i]); //asociate with tx sa SPI
2003     }
2004     else if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_SHA2_256) && (tx_sa[i].cipherMode == NWAL_SA_EALG_3DES_CBC))
2005     {
2006         /* static configuration, will not change */
2007         sa_info[i].tx_payload_info.aadSize = 0;
2008         sa_info[i].tx_payload_info.pAad = NULL;
2009         sa_info[i].tx_payload_info.authIvSize = 0;
2010         sa_info[i].tx_payload_info.pAuthIV = NULL;
2011         sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;        /*done: same for all cipher suites */
2012         sa_info[i].tx_payload_info.encIvSize = netTest_3DES_CBC_IV_LEN;
2013         sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN +
2014                                                                      netTest_IP_HEADER_LEN +
2015                                                                     netTest_ESP_HEADER_LEN +
2016                                                                     netTest_3DES_CBC_IV_LEN;
2018         /* dynamic configuration, will  be calculated on the fly */
2019         sa_info[i].tx_payload_info.authSize = 0;
2020         sa_info[i].tx_payload_info.encSize = 0;
2021         sa_info[i].tx_payload_info.ploadLen = 0;
2022         sa_info[i].tx_payload_info.pEncIV = 0;
2023         sa_info[i].tx_payload_info.pPkt = 0;
2025         sa_info[i].cipherMode = NWAL_SA_EALG_3DES_CBC;
2026         sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
2027         sa_info[i].auth_tag_size = netTest_ICV_LEN;  /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
2028 #ifdef EXPERIMENTAL
2029         sa_info[i].iv_len=8;
2030         sa_info[i].bl=8;
2031         sa_info[i].spi = tx_sa[i].spi;
2032         sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
2033         sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
2034 #endif
2036         sa_info[i].tx_pkt_info.enetPort = 0;
2037         sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
2038         sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
2039         sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
2040         sa_info[i].tx_pkt_info.startOffset = 0;
2041         sa_info[i].tx_pkt_info.lpbackPass = 0;
2042         sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
2043         sa_info[i].tx_pkt_info.pPkt = NULL;
2044         sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;
2045         sa_info[i].tx_pkt_info.saPayloadLen = 0;
2046         sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
2047        
2048         sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
2050        trie_insert(p_trie_sa,(char *)&(tx_sa[i].spi),4, (void *) &sa_info[i]); //asociate with tx sa SPI
2051     }
2052     else if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_MD5) && (rx_sa[i].cipherMode == NWAL_SA_EALG_NULL))
2053     {
2054         /* static configuration, will not change */
2055         sa_info[i].tx_payload_info.aadSize = 0;
2056         sa_info[i].tx_payload_info.pAad = NULL;
2057         sa_info[i].tx_payload_info.authIvSize = 0;
2058         sa_info[i].tx_payload_info.pAuthIV = NULL;
2059         sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;        /*done: same for all cipher suites */
2060         sa_info[i].tx_payload_info.encIvSize = netTest_NULL_IV_LEN;
2062         sa_info[i].tx_payload_info.encOffset =         netTest_MAC_HEADER_LEN +
2063                                                                      netTest_IP_HEADER_LEN +
2064                                                                     netTest_ESP_HEADER_LEN +
2065                                                                     netTest_NULL_IV_LEN;
2066 #ifdef EXPERIMENTAL
2067         sa_info[i].iv_len=0;
2068         sa_info[i].bl=4;
2069         sa_info[i].spi = tx_sa[i].spi;
2070         sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
2071         sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
2072 #endif
2075         /* dynamic configuration, will  be calculated on the fly */
2076         sa_info[i].tx_payload_info.authSize = 0;
2077         sa_info[i].tx_payload_info.encSize = 0;
2078         sa_info[i].tx_payload_info.ploadLen = 0;
2079         sa_info[i].tx_payload_info.pEncIV = 0;
2080         sa_info[i].tx_payload_info.pPkt = 0;
2082         sa_info[i].cipherMode = NWAL_SA_EALG_NULL;
2083         sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
2084         sa_info[i].auth_tag_size = netTest_ICV_LEN;  /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
2086         sa_info[i].tx_pkt_info.enetPort = 0;
2087         sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
2088         sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
2089         sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
2090         sa_info[i].tx_pkt_info.startOffset = 0;
2091         sa_info[i].tx_pkt_info.lpbackPass = 0;
2092         sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
2093         sa_info[i].tx_pkt_info.pPkt = NULL;
2094         sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN;
2095         sa_info[i].tx_pkt_info.saPayloadLen = 0;
2096         sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
2097        
2098         sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
2100        trie_insert(p_trie_sa,(char *)&(tx_sa[i].spi),4, (void *) &sa_info[i]); //asociate with tx sa SPI
2101     }
2102     else
2103         printf("build_sa_db(): invalid encryption/authentication combination selected\n");
2105     //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);
2106     
2107     
2112 #define CHECK_SET_PARAM(ARG1, ARG2)     \
2113     do { \
2114         if(strcmp(key, ARG1) == 0) { \
2115         if(data)strncpy(ARG2,data,CONFIG_STRING_LEN); \
2116         printf("CHECK_SET_PARM, match found, input cong string %s\n", ARG2); \
2117         continue; \
2118         } \
2119     } while(0)
2121 #define CHECK_SET_PARAM2(ARG1, ARG2,  ARG3)     \
2122     do { \
2123         if(strcmp(key, ARG1) == 0) { \
2124         if(data) strncpy(ARG2,data,CONFIG_STRING_LEN); \
2125         if(data2) strncpy(ARG3,data2,CONFIG_STRING_LEN); \
2126         printf("CHECK_SET_PARM, match found, input cong string %s %s\n", ARG2, ARG3); \
2127         continue; \
2128         } \
2129     } while(0)
2131 unsigned char hex2dec(char *p_s)
2133   int val;
2134   sscanf(p_s,"%x",&val); 
2135  return val&0xff;
2137 void parse_one_mac(char * p_mac_str, unsigned char *p_mac)
2139     int index = 0;
2140     int i;
2141     char *pch = strtok (&(p_mac_str[0]),"-");
2143     while (pch != NULL)
2144     {
2145          printf ("%s\n",pch);
2146          p_mac[index] = hex2dec(pch);
2147          index++;
2148          pch = strtok (NULL,"-");
2149     }
2150      printf("index value : %d\n", index);
2151     for (i=0; i<6;i++)
2152          printf("************mac0[%d]: 0x%x\n",i,  p_mac[i]);
2155 void parse_one_ip(char * p_ip_addr_str, unsigned char * p_ip)
2157     int index = 0;
2158     int i;
2159     char * pch = strtok (&p_ip_addr_str[0],".");
2161      while (pch != NULL)
2162      {
2163         printf ("xxxxx: %s\n",pch);
2164         p_ip[index] = atoi(pch);
2165         index++;
2166         pch = strtok (NULL,".");
2167     }
2168     printf("index value : %d\n", index);
2169     for (i=0; i<4;i++)
2170         printf("************ip[%d]: 0x%x\n",i, p_ip[i]);
2175 void parse_mac_address(netTestConfigFile_t *pConfig)
2177     if (strlen(&pConfig->mac0[0]))
2178         parse_one_mac(&pConfig->mac0[0],&config.mac0[0]);
2179     if (strlen(&pConfig->mac1[0]))
2180         parse_one_mac(&pConfig->mac1[0],&config.mac1[0]);
2182 void parse_ip_address(netTestConfigFile_t *pConfig)
2184     if (strlen(&pConfig->ip0[0]))
2185         parse_one_ip(&pConfig->ip0[0],&config.ip0.ipv4[0]);
2186     if (strlen(&pConfig->ip1[0]))
2187         parse_one_ip(&pConfig->ip1[0],&config.ip1.ipv4[0]);
2188     if (strlen(&pConfig->ip2[0]))
2189         parse_one_ip(&pConfig->ip2[0],&config.ip2.ipv4[0]);
2190     if (strlen(&pConfig->local_ipsec_ip[0]))
2191         parse_one_ip(&pConfig->local_ipsec_ip[0],&config.local_ipsec_ip.ipv4[0]);
2192     if (strlen(&pConfig->remote_ipsec_ip[0]))
2193     parse_one_ip(&pConfig->remote_ipsec_ip[0],&config.remote_ipsec_ip.ipv4[0]);
2197 void parse_ipsec_mode(netTestConfigFile_t *pConfig)
2200     printf("parse_ipsec_mode, string length %d\n", strlen(&pConfig->ipsec_mode_rx));
2201     if (strlen(&pConfig->ipsec_mode_rx[0]))
2202     {
2203         if (strcmp(pConfig->ipsec_mode_rx, "SIDEBAND") == 0)
2204         {
2205             config.ipsec_mode_rx = IPSEC_MODE_RX_SIDEBAND;
2206         }
2207         else if (strcmp(pConfig->ipsec_mode_rx, "INFLOW") == 0)
2208         {
2209             config.ipsec_mode_rx = IPSEC_MODE_RX_INFLOW;
2210         }
2211         else
2212             printf("parse_ipsec_mode(), invalid RX ipsec mode in config file \n");
2213     }
2215     if (strlen(&pConfig->ipsec_mode_tx[0]))
2216     {
2217         if (strcmp(pConfig->ipsec_mode_tx, "SIDEBAND") == 0)
2218         {
2219             config.ipsec_mode_tx = IPSEC_MODE_TX_SIDEBAND;
2220         }
2221         else if (strcmp(pConfig->ipsec_mode_tx, "INFLOW") == 0)
2222         {
2223             config.ipsec_mode_tx = IPSEC_MODE_TX_INFLOW;
2224         }
2225     else
2226         printf("parse_ipsec_mode(), invalid TX ipsec mode in config file \n");
2227     }
2229     printf("parse_ipsec_mode(): RX mode %d\n", config.ipsec_mode_rx);
2230     printf("parse_ipsec_mode(): TX mode %d\n", config.ipsec_mode_tx);
2232     
2235 #ifdef EXPERIMENTAL
2236 int n_routes=0;
2237 int n_dst_ips=0;
2238 void parse_routes(netTestConfigFile_t *pConfig)
2240 int i;
2241 int said=0;
2242 for(i=0;i<MAX_ROUTES;i++)
2244    int port;
2245    if (pConfig->routes[i][0])
2246    {
2247       port=atoi(&pConfig->ports[i][0]);
2248       if((port<1)||(port>2)) continue; //bad port #: only 1 or 2 valid
2249       if(strncmp(&pConfig->routes[i][0],"MAC",3)==0)
2250       {
2251          routes[i].out_port = port;
2252          parse_one_mac(&pConfig->routes[i][3],&routes[i].out_mac[0]);
2253          memcpy(&routes[i].out_mac[6], ((port==1) ?&config.mac0[0]: &config.mac1[0] ),6); 
2254          routes[i].out_mac[12]=0x08;
2255          routes[i].out_mac[13]=0x00;
2256          routes[i].sec_ptr=NULL;
2257          n_routes+=1;
2258       }
2259       else if (strncmp(&pConfig->routes[i][0],"SA",2)==0)
2260       {      
2261          said=atoi(&pConfig->routes[i][2]) ;
2262          routes[i].sec_ptr=&sa_info[said];
2263          n_routes+=1;
2264       }
2265    }
2267 our_router = route_init();
2268 for (i=0;i<MAX_ROUTES;i++)
2270   unsigned long ip_be;
2271   int route_index;
2272   if (pConfig->dst_ips[i][0])
2273   {
2274      parse_one_ip(&pConfig->dst_ips[i][0],(unsigned char *)&ip_be);
2275      sscanf(&pConfig->paths[i][0],"route%d",&route_index);
2276      route_add(our_router,&ip_be,&routes[route_index]);
2277      n_dst_ips+=1;
2278   }
2280 printf(">Route DB built.  %d entries\n",n_dst_ips);
2282 #endif
2283 static void parse_config_file(FILE * fpr, netTestConfigFile_t *pConfig)
2285     char line[MAX_LINE_LENGTH + 1];
2286     int i;
2287  
2288     char *key, *data, *ep, *data2;
2289     char tokens[] = " :=;\n";
2290     char temp_str[50];
2291     memset(line, 0, MAX_LINE_LENGTH + 1);
2292     memset(pConfig, 0, sizeof(netTestConfigFile_t));
2293     while (fgets(line, MAX_LINE_LENGTH + 1, fpr)) 
2294     {
2295         if(line[0]=='#') continue; //skip comment
2296         key  = (char *)strtok(line, tokens);
2297         data = (char *)strtok(NULL, tokens);
2298         data2 = (char *)strtok(NULL, tokens);
2299         if (!key) continue;
2300         if (!data) continue;
2302         if(strlen(data) == 0) 
2303         {
2304             continue;
2305         }
2307          CHECK_SET_PARAM(INIT_CONFIG_MAC0,&(pConfig->mac0[0]));
2308          CHECK_SET_PARAM(INIT_CONFIG_MAC1,&(pConfig->mac1[0]));
2309          CHECK_SET_PARAM(INIT_CONFIG_IP0,&(pConfig->ip0[0]));
2310          CHECK_SET_PARAM(INIT_CONFIG_IP1,&(pConfig->ip1[0]));
2311          CHECK_SET_PARAM(INIT_CONFIG_IP2,&(pConfig->ip2[0]));
2312          CHECK_SET_PARAM(INIT_CONFIG_LOCAL_IPSEC_IP,&(pConfig->local_ipsec_ip[0]));
2313          CHECK_SET_PARAM(INIT_CONFIG_REMOTE_IPSEC_IP,&(pConfig->remote_ipsec_ip[0]));
2314          CHECK_SET_PARAM(INIT_CONFIG_IPSEC_MODE_RX,&(pConfig->ipsec_mode_rx[0]));
2315          CHECK_SET_PARAM(INIT_CONFIG_IPSEC_MODE_TX,&(pConfig->ipsec_mode_tx[0]));
2316          CHECK_SET_PARAM(INIT_CONFIG_IPSEC_IF_NO,&(pConfig->ipsec_if_no[0]));
2317 #ifdef EXPERIMENTAL
2318     for(i=0;i<MAX_ROUTES;i++)
2319     {
2320         sprintf(temp_str,"route%d",i);
2321         CHECK_SET_PARAM2(temp_str,&pConfig->routes[i][0],&pConfig->ports[i][0] );
2322     }
2323     for(i=0;i<MAX_ROUTES;i++)
2324     {
2325         sprintf(temp_str,"dstip%d",i);
2326         CHECK_SET_PARAM2(temp_str,&pConfig->dst_ips[i][0],&pConfig->paths[i][0] );
2327     }
2328 #endif
2329          
2330     }
2331     parse_mac_address(pConfig);
2333     parse_ip_address(pConfig);
2335     parse_ipsec_mode(pConfig);
2336 #ifdef EXPERIMENTAL
2337      if (strlen(&pConfig->ipsec_if_no[0]))
2338         config.ipsec_if_no = atoi(&pConfig->ipsec_if_no[0]);
2339     parse_routes(pConfig);
2340 #endif
2343 static  netTestConfigFile_t config_file;
2344 /***************************************
2345  ********** test driver*****************
2346  ***************************************/
2347 int main(int argc, char **argv)
2349     int err,i;
2350     rlim_t oss,ss = 1024*1024;
2351     struct rlimit rl;
2353     Pktlib_HeapCfg      heapCfg;
2354     int32_t             errCode;
2355     Pktlib_HeapIfTable*  pPktifTable;
2356  
2357     FILE * fpr = NULL;
2361     err= getrlimit(RLIMIT_STACK,&rl);
2362     if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");
2363 #if 0
2364     rl.rlim_cur = ss;
2365     err=setrlimit(RLIMIT_STACK,&rl);
2366 i   f (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");
2367 #endif
2370     if (argc>=2)  np2process = atoi(argv[1]);
2371         printf("*************** np2process %d\n", np2process);
2372     if (np2process<0) np2process = NP; /* default */
2373     if (argc==3)  perslow = atoi(argv[2]);
2374     if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default
2375     if (argc>3) {printf("net_test  <no of pkts to process> <percent slow path>\n"); exit(1);}
2376 #if 1
2378 #if 0
2379     if (argc >= 2) 
2380     {
2381         fpr = fopen(argv[2], "r");
2382         if (fpr == NULL) 
2383         {
2384             printf("Error in opening %s input file\n", argv[2]);
2385         }
2386     } 
2387     else
2388 #endif
2389     {
2390         fpr = fopen(input_file_name, "r");
2391         if (fpr == NULL) 
2392         {
2393             printf("Error in opening %s input file\n", input_file_name);
2394         }
2395         else
2396         {
2397             parse_config_file(fpr,&config_file);
2398         }
2399     }
2401 #endif
2403     memset(&sa_info, 0, sizeof(sa_info));
2406 //real mode, so update our test packet mac header and ip header
2407 if (pktloopback==0)
2409 memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address
2410 memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses
2412 #if 0 
2413 our_router = route_init();
2414 for (i=0;i<n_dst_ips;i++)
2416   route_add(our_router,&ip[i],&routes[i]);
2418 #endif
2420 /*******************************************/
2421 /*************NETAPI STARTUP****************/
2422 /*******************************************/
2424 /* create netapi */
2425 netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);
2427 /* open the main heap */
2428 OurHeap = Pktlib_findHeapByName("netapi");
2429 if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}
2431 /* create two secondary heaps */
2432 /* Initialize the heap configuration. */
2433 memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
2435 pPktifTable = netapi_getPktlibIfTable();
2436 /* Populate the heap configuration */
2437 heapCfg.name                = "netapi-small";
2438 heapCfg.memRegion           = NETAPI_GLOBAL_REGION;
2439 heapCfg.sharedHeap          = 1;
2440 heapCfg.useStarvationQueue  = 0;
2441 heapCfg.dataBufferSize      = 512;
2442 heapCfg.numPkts             = 64;
2443 heapCfg.numZeroBufferPackets= 0;
2444 heapCfg.heapInterfaceTable.data_malloc  = pPktifTable->data_malloc;
2445 heapCfg.heapInterfaceTable.data_free    = pPktifTable->data_free;
2446 heapCfg.dataBufferPktThreshold   = 0;
2447 heapCfg.zeroBufferPktThreshold   = 0;
2449 specialSmall = Pktlib_createHeap(&heapCfg, &errCode);
2450 heapCfg.name                = "netapi-big";
2451 heapCfg.dataBufferSize      = 1600;
2452 specialLarge = Pktlib_createHeap(&heapCfg, &errCode);
2453 //register these heaps so poll routine will include their garbage queues.
2454 netapi_registerHeap(netapi_handle, specialSmall);
2455 netapi_registerHeap(netapi_handle, specialLarge);
2457 #ifdef REASSEMBLE_BENCH
2458 our_reassemble_bench(2);
2459 exit(1);
2460 #endif
2462 #ifndef EXPERIMENTAL
2463 /* create a pktio channel */
2464 our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb_bench, &our_chan_cfg,&err);
2465 if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}
2466 #endif
2468 /* open netcp default tx, rx queues */
2469 netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
2470 if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}
2471 #ifdef EXPERIMENTAL
2472 netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg,  &err);
2473 #else
2474 netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg,  &err);
2475 #endif
2476 if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
2478 #ifndef EXPERIMENTAL
2479 /* create a pktio channel for specially classified pkts */
2480 netcp_rx_chan2= pktio_create(netapi_handle, "classq", (PKTIO_CB) recv_cb, &netcp_rx_cfg2,  &err);
2481 if (!netcp_rx_chan2) {printf("pktio create RX2 failed err=%d\n",err); exit(1);}
2483 /* open netcp default tx, rx queues for sideband crypto */
2484 netcp_sb_tx_chan= pktio_open(netapi_handle, NETCP_SB_TX, NULL, &netcp_sb_tx_cfg,  &err);
2485 if (!netcp_sb_tx_chan) {printf("pktio open SB TX failed err=%d\n",err); exit(1);}
2486 netcp_sb_rx_chan= pktio_open(netapi_handle, NETCP_SB_RX, (PKTIO_CB) recv_sb_cb, &netcp_sb_rx_cfg,  &err);
2487 if (!netcp_sb_rx_chan) {printf("pktio open SB RX failed err=%d\n",err); exit(1);}
2488 #endif
2490 printf("net_test> %d bytes left in our CMA area\n", netapi_getBufMemRemainder());
2491 /* create scheduler instance */
2492 our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
2493 if (!our_sched) {printf("sched create failed\n"); exit(1);}
2495 #if 0
2496 /********************************************
2497 * Basic pkt loopback test
2498 *********************************************/
2499 printf("...running pure push/pop benchmark\n");
2500 our_pktio_bench(1000);
2501 our_pktio_bench(1000);
2502 our_pktio_bench(1000);
2503 our_pktio_bench(1000);
2504 our_pktio_bench(1000);
2505 /*********************************************/
2506 #endif
2511 /* add mac intefaces */
2512 netcp_cfgCreateMacInterface(
2513                   netapi_handle,
2514                   &config.mac0[0],
2515                   0,0,
2516                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
2517                   (NETCP_CFG_VLAN_T ) NULL ,  //future
2518                   1, 
2519                   &err);
2520 if (err) {printf("addmac0 failed %d\n",err); exit(1); } 
2522 //attach an IP to this interface
2523 ip_rule0=netcp_addIp(
2524                   netapi_handle,
2525                   0,
2526                   nwal_IPV4,
2527                   &config.ip0,
2528                   NULL,  //all IP
2529                   (NETCP_CFG_ROUTE_HANDLE_T) NULL,
2530                   &err
2531                   );
2532 if (err) {printf("addip0 failed %d\n",err); exit(1); } 
2534 //create a 2nd mac instance
2535 netcp_cfgCreateMacInterface(
2536                   netapi_handle,
2537                   &config.mac1[0],
2538                   1,1,
2539                   (NETCP_CFG_ROUTE_HANDLE_T)  NULL,
2540                   (NETCP_CFG_VLAN_T ) NULL ,  //future
2541                   1,
2542                   &err);
2543 if (err) {printf("addmac1 failed %d\n",err); exit(1); }
2545 //attach an IP to this interface
2546 ip_rule1=netcp_addIp(
2547                   netapi_handle,
2548                   1,
2549                   nwal_IPV4,
2550                   &config.ip1,
2551                   NULL,  //all IP
2552                   (NETCP_CFG_ROUTE_HANDLE_T) NULL,
2553                   &err
2554                   );
2555 if (err) {printf("addip1 failed %d\n",err); exit(1); }
2557 #ifndef EXPERIMENTAL
2558 //attach 2 classifiers to iface 0, ip0
2559 class_0_cfg.u.c_l4.ip = ip_rule0;
2560 class_0 =  netcp_cfgAddClass(netapi_handle,
2561                              &class_0_cfg,
2562                              NULL,
2563                              NETCP_CFG_ACTION_TO_SW,
2564                              &err);
2565 if (err) {printf("addclass0 failed %d\n",err); exit(1);}
2567 class_1_cfg.u.c_l4.ip = ip_rule0;
2568 class_1 =  netcp_cfgAddClass(netapi_handle,
2569                              &class_1_cfg,
2570                              NULL,
2571                              NETCP_CFG_ACTION_TO_SW,
2572                              &err);
2573 if (err) {printf("addclass1 failed %d\n",err); exit(1);}
2576 //3rd classifier has a different IP and route
2577 class_2_cfg.u.c_l3_l4.ip_addr = &config.ip2;
2579 //create specialFlow for this classifier
2581 Pktlib_HeapHandle heaps[2];
2582 int sizes[2];
2583 heaps[0]= specialSmall;
2584 heaps[1]= specialLarge;
2585 #define SPECIAL_SOP_OFF 128
2586 sizes[0]=512-SPECIAL_SOP_OFF;
2587 sizes[1]=1600-SPECIAL_SOP_OFF;
2588 #if 0
2589 specialFlow = netcp_cfgAddFlow( netapi_handle,
2590                                 2,
2591                                 heaps,
2592                                 sizes,
2593                                 SPECIAL_SOP_OFF,  //offset to start rx is 128 
2594                                 &err);
2595 if (err) {printf("add flow failed\n", err); exit(1);}
2596 #endif
2598 #if 0
2599 //special route for this classifier:  different flow + destination q
2600 class2_route.p_dest_q = netcp_rx_chan2;
2601 class2_route.p_flow = specialFlow;
2602 class_2 = netcp_cfgAddClass(netapi_handle,
2603                             &class_2_cfg,
2604                             (void*) &class2_route,
2605                             NETCP_CFG_ACTION_TO_SW,
2606                             &err);
2607 if (err) {printf("addclass2 failed %d\n",err); exit(1);}
2608 #endif
2610 #endif
2611 //security stuff 
2612     p_trie_sa = trie_new();
2613    if (!p_trie_sa) {printf("trie alloc for SA  failed\n"); exit(1);}
2617     for (i=0; i < MAX_SEC_INDEX;i++)
2618     {
2619         ourRXKeyParams[i].pEncKey = &ourEncrKey[0];
2620         ourRXKeyParams[i].pAuthKey = &ourAuthKey[0];
2621         memcpy(&(rx_sa[i].src), &config.remote_ipsec_ip,4);
2622         memcpy(&(rx_sa[i].dst), &config.local_ipsec_ip,4);
2624         build_sa_db(i);
2625         sa_info[i].rx_tunnel = netapi_secAddSA(
2626             netapi_handle,
2627             config.ipsec_if_no, //iface #0 
2628             &rx_sa[i],
2629             &ourRXKeyParams[i],
2630             config.ipsec_mode_rx == IPSEC_MODE_RX_SIDEBAND ? NETAPI_SEC_SA_SIDEBAND: NETAPI_SEC_SA_INFLOW,
2631                 NULL,  //use default route 
2632             &(sa_info[i].rx_data_mode_handle),
2633             &(sa_info[i].rx_inflow_mode_handle),
2634             &err);
2635         if (err) {printf("addRxSa failed %d\n",err); exit(1);}
2637     if (config.ipsec_mode_rx == IPSEC_MODE_RX_INFLOW)
2638     {
2639         //assume inner and outer ip is the same
2640         rx_policy[i]= netapi_secAddRxPolicy( netapi_handle,
2641                          sa_info[i].rx_tunnel,  //link to tunnel above
2642                          4,         //ipv4
2643                          &config.remote_ipsec_ip, //src -> them
2644                          &config.local_ipsec_ip,  //dst -> us
2645                         NULL,  // no qualifiers
2646                         NULL,  //default route
2647                          &err);
2648         if (err) {printf("addSaPolicy failed  %d, for index %d\n",err,i); exit(1);}
2649     }
2650     else 
2651         rx_policy[i] = 0;
2652     }
2654 //tx SA
2655 //security stuff 
2656      for (i=0; i < MAX_SEC_INDEX;i++)
2657     {
2658     ourTXKeyParams[i].pEncKey = &ourEncrKey[0];
2659     ourTXKeyParams[i].pAuthKey = &ourAuthKey[0];
2660     memcpy(&(tx_sa[i].src), &config.local_ipsec_ip,4);
2661     memcpy(&(tx_sa[i].dst), &config.remote_ipsec_ip,4);
2662     sa_info[i].tx_tunnel = netapi_secAddSA( netapi_handle,
2663                  0, //iface #0 
2664                 &(tx_sa[i]),
2665                 &ourTXKeyParams[i],
2666                 config.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND ? NETAPI_SEC_SA_SIDEBAND: NETAPI_SEC_SA_INFLOW,
2667                 NULL,  //use default route 
2668                 &(sa_info[i].tx_data_mode_handle),
2669                 &(sa_info[i].tx_inflow_mode_handle),
2670                 &err);
2671 if (err) {printf("addTxSa failed %d\n",err); exit(1);}
2673     }
2674 #ifdef TEST_TIMERS
2675 //timers
2676 ourTimerBlock = netapi_TimerGroupCreate(
2677         netapi_handle,
2678         "our1sttimer",
2679         our_timer_cb,
2680         0,    //1 if timers local to thread
2681         0,    //1 if expect to cancel
2682         netapi_getTicksPerSec()/1000,  /* 1 msc resolution for these timers */
2683         netapi_getTicksPerSec()/5000, /* would like .5 msc tolerence */
2684         10,  //small # of timers to test garbage collection
2685         &err);
2686 if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}
2688 //start a couple of timers 
2689 t1 = netapi_TimerGroupStartTimer(
2690         ourTimerBlock,
2691         (void *) 1,
2692         100LL,  //timer group ticks
2693         &err);
2694 if (err) {printf("timerstart failed %d\n");}
2695 t2 = netapi_TimerGroupStartTimer(
2696         ourTimerBlock,
2697         (void *) 2,
2698         200LL,  //timer group ticks
2699         &err);
2700 if (err) {printf("timerstart failed %d\n");}
2701 t3 = netapi_TimerGroupStartTimer(
2702         ourTimerBlock,
2703         (void *) 3,
2704         300LL,  //timer group ticks
2705         &err);
2706 if (err) {printf("timerstart failed %d\n");}
2707 #endif
2708 netcp_cfgReqStats(netapi_handle, our_stats_cb, 1,&err);
2709 if (err!=0) {printf("stats req failed\n");}
2711 /*********************************************/
2712 /*****************end NETAPI STARTUP**********/
2713 /*********************************************/
2716 #if 0
2717 /********************************************
2718 * Basic pkt loopback test
2719 *********************************************/
2720 printf("...runnining pure push/pop benchmark\n");
2721 our_pktio_bench(100);
2722 #endif
2724 /**************unused stuff******************/
2725 #if 0
2726 /* create TRIE */
2727 P_trie = trie_new();
2728 if (!P_trie) {printf("trie alloc failed\n"); exit(1);}
2730 nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T));
2731 if (!nat) {printf("malloc of nat table failed\n"); exit(1);}
2733 //gen_pkts(np2process<NP ? np2process:NP);
2734 n_pkt= np2process;
2736 /* build table */
2737 build_table(P_trie);
2740 /* processing loop: get pkt, check it, look up in table, copy new header,
2741    send packet */
2742 srand((unsigned) np2process);
2743 #endif
2745 /*********************************************/
2746 /**************Entry point into scheduler ****/
2747 /*********************************************/
2748 netapi_schedWaitForEvents(our_sched, &err);
2750 /* done */
2751 our_stats_cb(netapi_handle, NULL);
2754 #define DO_FAST_POLL
2755 #ifdef DO_FAST_POLL
2756 //example_fast_pushpop(OurHeap, 500);
2757 //example_fast_poll(netcp_rx_chan,20000);
2758 #endif
2760 /*************************************************
2761  ************CLEAN UP****************************
2762  ************************************************/
2764 #ifndef EXPERIMENTAL
2765 //delete Classifiers
2766 netcp_cfgDelClass(netapi_handle, class_0, &err); 
2767 netcp_cfgDelClass(netapi_handle, class_1, &err); 
2768 //netcp_cfgDelClass(netapi_handle, class_2, &err); 
2770 #if 0
2771 //delete flow 
2772 netcp_cfgDelFlow(netapi_handle, specialFlow, &err);
2773 #endif
2774 #endif
2775 #if 1
2776 //delete policy
2777      for (i=0; i < MAX_SEC_INDEX;i++)
2778     {
2779         if (rx_policy[i])
2780             netapi_secDelRxPolicy(netapi_handle, rx_policy[i], &err);
2781      
2782         //delete tunnels
2783         netapi_secDelSA(netapi_handle, 0, sa_info[i].rx_tunnel, &err);
2784         netapi_secDelSA(netapi_handle, 0, sa_info[i].tx_tunnel, &err);
2785 #endif
2786     }
2787 //delete IPs and MAC Interfacess
2788 netcp_cfgDelIp(netapi_handle, 0, 0, NULL, NULL, ip_rule0, &err);
2789 netcp_cfgDelIp(netapi_handle, 1, 0, NULL, NULL, ip_rule1, &err);
2790 netcp_cfgDelMac(netapi_handle,0,&err);
2791 netcp_cfgDelMac(netapi_handle,1,&err);
2794 //close pktio channels we opened
2795 pktio_close(netcp_tx_chan ,&err);
2796 pktio_close(netcp_rx_chan ,&err);
2797 #ifndef EXPERIMENTAL
2798 pktio_close(netcp_sb_tx_chan ,&err);
2799 pktio_close(netcp_sb_rx_chan ,&err);
2801 //clear pktio channel we created
2802 pktio_control(our_chan, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channel_control, &err);
2803 pktio_control(netcp_rx_chan2, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channel_control, &err);
2805 //delete pktio channels we created
2806 pktio_delete(our_chan, &err);
2807 pktio_delete(netcp_rx_chan2,&err);
2808 #endif
2809 netapi_shutdown(netapi_handle);
2813 //EXAMPLE FAST POLL
2814 /* PLD */
2815 void netapi_pld(void * x)
2816 {   
2817            asm volatile("pld [r0]");
2819 #include "ti/drv/nwal/nwal_util.h"
2821 #define M 1008
2822 static int l3_off[M], l4_off[M], L3_chk_ok[M], L4_chk_ok[M], len[M] ;
2823 static nwal_AppId appid[M];
2824 static unsigned char * buf[M];
2825 #define N2POLL 8 //batch size
2826 #define NTOPOP 190
2827 Ti_Pkt * pHd[NTOPOP];
2828 void example_fast_pushpop(Pktlib_HeapHandle h , int n_trials)
2830 int i,j;
2831 unsigned long t1;
2832 unsigned long t2;
2833 unsigned long sumf=0;
2834 unsigned long sumt=0;
2835 unsigned long sump=0;
2836 #define NTOPOP 190
2837 Ti_Pkt * tempVA;
2838 Qmss_QueueHnd freeQ=Pktlib_getInternalHeapQueue(h);
2840 //n_trials of NTOPOP actions
2841 for(i=0;i<n_trials;i++)
2843     //raw pop
2844     t1= netapi_timing_start();
2845     pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (freeQ));
2846     for(j=1;j<NTOPOP;j++)
2847     {
2848        tempVA  =  _Osal_qmssPhyToVirt(pHd[j-1]);
2849        netapi_pld(tempVA);
2850         //__builtin_prefetch(tempVA);
2851        pHd[j] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (freeQ));
2852        sumf+= (int) (   ((Cppi_HostDesc *) tempVA)->origBuffPtr -
2853                   ((Cppi_HostDesc *) tempVA)->buffPtr);
2854     }
2855     tempVA  =  _Osal_qmssPhyToVirt(pHd[j-1]);
2856     sumf+= (int) (   ((Cppi_HostDesc *) tempVA)->origBuffPtr -
2857                   ((Cppi_HostDesc *) tempVA)->buffPtr);
2858     t2=netapi_timing_stop();
2859     sumt+= (t2-t1);
2861     //invalidate/wb 
2862     for(j=0;j<NTOPOP;j++)
2863     {
2864         tempVA  =  _Osal_qmssPhyToVirt(pHd[j]);
2865         netapi_utilCacheWbInv(tempVA,128);
2866     }
2868     //raw push 
2869     t1=netapi_timing_start();
2870     for(j=0;j<NTOPOP;j++)
2871     {
2872         PKTIO_QMSS_QUEUE_PUSH_DESC_SIZE_RAW (freeQ,
2873                                              (void *) pHd[j],
2874                                              128);
2875     }
2876     t2=netapi_timing_stop();
2877     sump += (t2-t1);
2879 printf("\nfast poppush: np=%d  pop=%d  push=%d sumf=%d\n", (n_trials*NTOPOP),
2880         sumt/(n_trials*NTOPOP),  sump/(n_trials*NTOPOP), sumf);
2881 sleep(1);
2882 return;
2887 void example_fast_poll( PKTIO_HANDLE_T * p_pktio, int max_pkts)
2889 int j=0;
2890 int jj=0;
2891 int i,k,l=0,ltot=0;
2892 int n= N2POLL; //max # of pkts to poll
2893 Ti_Pkt * tempVA;
2894 pasahoLongInfo_t* pinfo;
2895 unsigned long t1;
2896 unsigned long t2;
2897 unsigned long t11;
2898 unsigned long t12;
2899 unsigned long np;
2900 unsigned long sumt=0;
2901 unsigned long sumf=0;
2902 unsigned long sump=0;
2903 unsigned long totlen=0;
2904 int max_batch=0;
2906 //this should  be done once and saved
2907 Qmss_QueueHnd rxQ= PKTIO_GET_DEFAULT_NETCP_Q(p_pktio);
2908 Qmss_QueueHnd freeQ;
2909 //loop forever
2910 for(;max_pkts>0;)
2912     t1= netapi_timing_stop();
2913     pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
2914     if (!pHd[0]) continue;
2915     //got pkt
2916     for(i=1;(i<n) && (pHd[i-1]);i++)
2917     {
2918         //convert previous descriptor PA -> VA
2919         tempVA  =  Osal_qmssPhyToVirt(pHd[i-1]); 
2921         //try and preload desriptor
2922          __builtin_prefetch(tempVA);
2923         //netapi_pld(tempVA);
2925         //read next descriptor from queue 
2926         pHd[i] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
2927 #if 1   
2928         /* extract some meta data */
2929         Cppi_getData (Cppi_DescType_HOST, (Cppi_Desc*)tempVA, &buf[jj], &len[jj]);
2930         pinfo =  nwal_mGetProtoInfo(tempVA);
2931         l3_off[jj]= nwal_mGetL3OffBytes(pinfo);
2932         l4_off[jj]= nwal_mGetL4Offset(pinfo);
2933         if(nwal_mGetAppidFmPkt(tempVA,&appid[jj]) != nwal_TRUE)
2934         {
2935             printf("ERROR!!!! AppID not available in incoming packet \n");
2936         }
2937 //#define VERIFY_SOP
2938 #ifdef VERIFY_SOP
2939   if (sump < 200)  printf("..sop off=%d\n", (int) buf[jj]-
2940            (int)  ((Cppi_HostDesc *) tempVA)->origBuffPtr) ;
2941 #endif
2942 #endif
2943         jj+=1;
2944     }
2945     //finish last pkt in burst
2946     if(pHd[i-1])
2947     {
2948         //convert previous descriptor PA -> VA
2949         tempVA  =  Osal_qmssPhyToVirt(pHd[i-1]); 
2951         /* extract some meta data */
2952 #if 1
2953         pinfo =  nwal_mGetProtoInfo(tempVA);
2954         l3_off[jj]= nwal_mGetL3OffBytes(pinfo);
2955         l4_off[jj]= nwal_mGetL4Offset(pinfo);
2956         if(nwal_mGetAppidFmPkt(tempVA,&appid[jj]) != nwal_TRUE)
2957         {
2958             printf("ERROR!!!! AppID not available in incoming packet \n");
2959         }
2960 #endif
2961         //get ptr (Physical address) and length of associate buffer
2962         Cppi_getData (Cppi_DescType_HOST, (Cppi_Desc*)tempVA, &buf[jj], &len[jj]);
2963         jj+=1;
2964     }
2965     t2= netapi_timing_stop();
2966     j+=(pHd[i-1]? i: (i-1)) ;
2967     if (jj>(M-n)) jj=0;
2968     l+=1;  //n batches
2969     ltot+=1;
2970     if(pHd[i-1])
2971     {
2972       if (i>max_batch) max_batch= i;
2973     }
2974     else
2975     {
2976       if( (i-1) >max_batch) max_batch = i-1;
2977     }
2979     //cleanup
2980     //printf("cleanup %d\n",i);
2981     for(k=0;k<i;k++)
2982     {
2983         //cleanup.  need to covert all of desriptor to VA so that i can use freePacket() 
2984         //alternative would be to just do cache ops plus descriptor raw push to pktlib
2985         // heap free queue
2986         if(pHd[k])
2987         {
2989         //tempVA=Qmss_osalConvertDescPhyToVirt(pHd[k]);
2990         tempVA  =  Osal_qmssPhyToVirt(pHd[k]);
2991         freeQ=Qmss_getQueueHandle(Cppi_getReturnQueue (Cppi_DescType_HOST, (Cppi_Desc *)tempVA));
2992         netapi_utilCacheWbInv(tempVA,128);
2993         //would need to wbInv buffer also in practice. Also need to walk
2994         // descriptor chain 
2995         t11= netapi_timing_stop();
2996        // Pktlib_freePacket(tempVA);
2997         PKTIO_QMSS_QUEUE_PUSH_DESC_SIZE_RAW (freeQ,
2998                                              (void *) pHd[k],
2999                                              128);
3001         t12= netapi_timing_stop();
3002         sumf += (t12-t11);       
3003         }
3004     }
3005     sumt += (t2-t1);
3006     sump +=(pHd[i-1]? i: (i-1));
3007     max_pkts -= (pHd[i-1]? i: (i-1));
3009     //printf("end cleanup %d %d %d\n",sumt,sumf,sump );
3010     if (sump > 10000) {
3011        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", 
3012                   j,ltot, appid[j%M], 
3013                   l3_off[j%M],l4_off[j%M],  
3014                   len[j%M],buf[j%M],
3015                    sumt/sump,  (sump*1000)/l, max_batch,
3016                    sumf/sump);
3017        sumt=sump=sumf=0;
3018        l=0;
3019     }
3022     //cleanup any remaining buffers
3023     for(;;)
3024     {
3025         pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
3026         if(!pHd[0]) break;
3027         tempVA  =  Osal_qmssPhyToVirt(pHd[0]);
3028         freeQ=Qmss_getQueueHandle(Cppi_getReturnQueue (Cppi_DescType_HOST, (Cppi_Desc *)tempVA));
3029         netapi_utilCacheWbInv(tempVA,128);
3030         PKTIO_QMSS_QUEUE_PUSH_DESC_SIZE_RAW (freeQ,
3031                                              (void *) pHd[0],
3032                                              128);
3033     }
3036 #ifdef EXPERIMENTAL
3038 static inline void send_it(Ti_Pkt *tip, int len, ROUTE_SEC_T * p_sec)
3040   unsigned long st1;
3041   unsigned long st2;
3042   int err=0;
3043   PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
3044   nwalTxPktInfo_t meta_tx2={0};
3045   st1=netapi_timing_start();
3046   if (len<60) 
3047   { 
3048      unsigned int templen;
3049      char * p_pkt;
3050      len=60; 
3051      Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
3052      Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
3053      stats.tx_min+=1;
3054   }
3055   Pktlib_setPacketLen(tip,len);
3056   meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
3057   meta_tx2.startOffset = 0;
3058   meta_tx2.ipOffBytes = 14;
3059   meta_tx2.ploadLen = len ;
3060   if(p_sec)
3061   {   
3062        meta_tx2.txFlag1 |= NWAL_TX_FLAG1_DO_IPSEC_CRYPTO ;
3063        meta2.sa_handle=p_sec->tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied
3064        meta_tx2.enetPort=0;
3065        meta_tx2.saOffBytes=14+20;
3066        meta_tx2.saPayloadLen=len-14-20;   //don't include tag, mac and outer header
3067        stats.sec_tx+=1;
3068   }
3069   meta2.u.tx_meta=&meta_tx2;
3070   pktio_send(netcp_tx_chan,tip,&meta2,&err);
3071   stats.tx +=1;
3072   st2=netapi_timing_start();
3073   stats.send_cycles += (unsigned long long) (st2-st1);  
3074
3075 void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
3076                          PKTIO_METADATA_T meta[], int n_pkts,
3077                          uint64_t ts )
3079 int i;
3080 int len;
3081 int p;
3082 Ti_Pkt * tip;
3083 unsigned int templen;
3084 char * p_pkt;
3085 HEAD_T temp_head;
3086 unsigned int appid;
3087 IP_HEAD_T th;
3088 ROUTE_SEC_T *sec_data=NULL;
3089 unsigned long t1;
3090 unsigned long t2;
3091 unsigned long ct1;
3092 unsigned long ct2;
3093 unsigned short ip_pl;
3094 int n_c_ops;
3095 t1=netapi_timing_start();
3096 ct1 =Osal_cache_op_measure(&n_c_ops);
3097 for(i=0;i<n_pkts;i++)
3099         tip = p_recv[i];
3100         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
3101         len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
3102         stats.rx+=1;
3103         appid = ((unsigned int)meta[i].u.rx_meta->appId)&0xff000000;
3104         switch(appid)
3105         {
3106            case(NETAPI_NETCP_MATCH_IPSEC):
3107            case(NETAPI_NETCP_MATCH_IPSEC_POLICY):
3108            {
3109              int tailen=12+2;
3110              memcpy(&temp_head,&p_pkt[14],sizeof(HEAD_T));
3111              if (!check_header(&temp_head,&meta[i])) {
3112                 stats.n_bad+=1;
3113                 Pktlib_freePacket(tip); 
3114                 continue;
3115              }
3116              tailen+=p_pkt[len-12-2]; //padding length  (12)should come from sec_ptr
3117              p_pkt = &p_pkt[8+16+20];   //16= iv len, should come from sec_ptr
3118              len -= (8+16+20+tailen);  //16= iv len should come from sec ptr
3119             
3120              //now check inner headder.
3121              memcpy(&th,&p_pkt[14],20);
3122              if (!check_header(&temp_head,&meta[i])) {
3123                 stats.n_bad+=1;
3124                 Pktlib_freePacket(tip);
3125                 continue;
3126              }
3127              Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
3128              Pktlib_setPacketLen(tip,len);
3129              
3130              if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data)<0)
3131               {
3132                 stats.n_bad+=1;
3133                 Pktlib_freePacket(tip);
3134              }
3135              else
3136              {
3137                send_it(tip,len,sec_data);
3138              }
3139              break;
3140            }
3141            case(NETAPI_NETCP_MATCH_GENERIC_MAC):
3142               if((p_pkt[12]!=0x8)||(p_pkt[13]!=0x00)) 
3143               {
3144                 stats.n_new+=1;
3145                 Pktlib_freePacket(tip); 
3146                 continue;
3147               }
3148               if (!check_header(&temp_head,&meta[i])) 
3149               {
3150                 stats.n_bad+=1;
3151                 Pktlib_freePacket(tip);
3152                 continue;
3153               }
3154               memcpy(&th,&p_pkt[14],20);
3155               ip_pl= (((unsigned char *)&th.w1)[2]<<8) | ((unsigned char *)&th.w1)[3];
3156               if ((ip_pl+14)<60)
3157               {
3158                 len-= (60-(ip_pl+14));
3159                 stats.rx_min+=1;
3160               }
3161               Pktlib_setPacketLen(tip,len);
3162               if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data)<0)
3163               {
3164                 stats.n_bad+=1;
3165                 Pktlib_freePacket(tip);
3166               }
3167               else
3168               {
3169                  send_it(tip,len,sec_data);
3170               }
3171               break;
3172            case(NETAPI_NETCP_MATCH_GENERIC_IP):
3173               Pktlib_freePacket(tip); 
3174               stats.n_new=1;
3175               break;
3176            default:
3177               stats.n_new+=1;
3178               Pktlib_freePacket(tip);
3179               break;
3180        }
3182 t2=netapi_timing_start();
3183 ct2 =Osal_cache_op_measure(&n_c_ops);
3184 stats.app_cycles +=  (unsigned long long) (t2-t1);
3185 stats.tx_cache_cycles += (unsigned long long) (ct2-ct1);
3186 return;
3188 #endif