Updated netapi makefile to use correct DEVICE define, net_test cleanup, version update.
[keystone-rtos/netapi.git] / ti / runtime / netapi / test / net_test_router.c
1 /******************************************************************************
2  * File: net_test_router.c
3  * Purpose: net_test_router application
4  ******************************************************************************
5  * FILE:  net_test_router.c
6  * 
7  * DESCRIPTION:  netapi user space transport
8  *               library  net_test_router application
9  * 
10  * REVISION HISTORY:
11  *
12  *  Copyright (c) Texas Instruments Incorporated 2013
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 "trie.h"
46 #include <signal.h>
47 #include <pthread.h>
48 #include <sys/resource.h>
49 #include "router.h"
50 extern int QUIT;
52 /* Global definitions */
53 #ifdef netTest_MULTI_THREAD
54     cpu_set_t cpu_set;
55 #endif
57 netTestConfig_t netTestCfg;
58 static  netTestConfigFile_t config_file;
60 char    input_file_name[] = "net_test_config.txt";
62 nwal_RetValue       nwalRetVal;
63 Pktlib_HeapHandle ourHeap;
65 PKTIO_HANDLE_T *netcp_tx_chan_no_crypto;
66 PKTIO_HANDLE_T *netcp_rx_chan;
67 PKTIO_HANDLE_T *netcp_tx_chan_esp;
68 PKTIO_HANDLE_T *netcp_tx_chan_ah;
73 PKTIO_CFG_T netcp_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};
74 PKTIO_CFG_T netcp_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};
78 NETCP_CFG_EXCEPTION_PKT_T expPkt_appid;
80 Trie *p_trie_sa_rx;
81 Trie *p_trie_sa_tx;
84 #include "router.c"
85 Trie * our_router;
87 OUR_ROUTE_T routes[MAX_ROUTES]=
89 {
90     {0,{0xD4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x14,0x02,0x08,0x00},0},
91     {0,{0x00,0x00,0x0,0x00,0x0,0x0, 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00},0},
92     {0,{0xD4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x14,0x02,0x08,0x00},0},
93     {0,{0x00,0x15,0x60,0xa1,0xf7,0xbe, 0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00},0},
94     {0,{0xd4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00},0}
95 };
96 unsigned int ip[MAX_ROUTES]={BE(0x0a0100c8),BE(0x0a00000a),BE(0x0a02000a),BE(0xc0a8010a),BE(0x9eda6719)};
98 void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
99                          PKTIO_METADATA_T meta[], int n_pkts,
100                          uint64_t ts );
103 extern netTestStats_T stats[TUNE_NETAPI_NUM_CORES];
104 extern paSysStats_t netcp_stats;
106 /*******************************************
107  *************NETAPI OBJECTS***************
108  *****************************************/
109 static NETAPI_CFG_T our_netapi_default_cfg=
111 TUNE_NETAPI_PERM_MEM_SZ,
112 128,  //start of packet offset for hw to place data on rx for default flow
113 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
114 TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
115 TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
116 64, //#descriptors w/o buffers in default heap
117 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
118 128   ,  //tail room
119 256      //extra room 
120 };
124 void house(NETAPI_SCHED_HANDLE_T *s);
125 NETAPI_T netapi_handle;
126 NETAPI_SCHED_HANDLE_T * our_sched;
127 #ifdef netTest_MULTI_THREAD
128 NETAPI_SCHED_HANDLE_T * scheduler[TUNE_NETAPI_NUM_CORES];
129 #endif
130 NETAPI_SCHED_CONFIG_T our_sched_cfg={
131   NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000  //every 5000000 poll loops
132 };
135 NETCP_CFG_IP_T ip_rule[NET_TEST_MAX_IP];
136 NETCP_CFG_MACIF_T mac[NET_TEST_MAX_MAC];
140 /* security objects. (for loopback mode) */
141 netTestSA_t sa_info[MAX_SEC_INDEX];
144 NETCP_CFG_IPSEC_POLICY_T rx_policy[MAX_SEC_INDEX];
149 /*************************END NETAPI OBJECTS***********************/
151 void update_header(netTestHead_T * p_head, int len)
153    unsigned char *p = (unsigned char *) &p_head->udp[1];
154    len -= (20+14);
155    /* update ip checksum */
156    /* update udp checksum */
157    /* update length */
158    *p= (len&0xff00)>>8;
159    *(p+1) = len&0xff;
162 #ifdef netTest_MULTI_THREAD
163 /* Templates to build command labels at startup up time, required by open_pktio_tx_channels() */
164 nwalTxPktInfo_t txPktInfoESP = 
166     NULL,                                                                                               /* p_pkt */
167     NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID,      /* txFlags */
168     0,                                                                                                  /* lpbackPass */
169     1,                                                                                                  /* enetport */
170     0,                                                                                                  /* msuSize */
171     0,                                                                                                   /* startOffset */
172     netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN,                                                    /* saOffBytes */
173     0,                                                                                                  /* saPayLoadLen */
174     0               ,                                                                                    /* saAhIcvOffBytes */
175     0,                                                                                                 /* saAhMacSize */
176     0,                                                                                                  /* etherLenOffBytes */
177     netTest_MAC_HEADER_LEN,                                                        /* ipOffBytes */
178     0,                                                                                                  /* l4OffBytes */
179     0,                         /* l4HdrLen */
180     0,                                                                                   /* pseudoHdrChecksum */
181     0                                                                                                   /* pLoadLen */
182 };
185 nwalTxPktInfo_t txPktInfoAH = 
187     NULL,                                                                                               /* p_pkt */
188     NWAL_TX_FLAG1_DO_IPSEC_AH_CRYPTO| NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_META_DATA_VALID,      /* txFlags */
189     0,                                                                                                  /* lpbackPass */
190     0,                                                                                                  /* enetport */
191     0,                                                                                                  /* msuSize */
192     0,                                                                                                   /* startOffset */
193     netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN,                                                    /* saOffBytes */
194     0,                                                                                                  /* saPayLoadLen */
195     netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN + netTest_IPSEC_AH_FIXED_HDR_SIZE,                    /* saAhIcvOffBytes */
196     12,                                                                                                 /* saAhMacSize */
197     0,                                                                                                  /* etherLenOffBytes */
198     netTest_MAC_HEADER_LEN,   /* ipOffBytes */
199     0,                                                                                                  /* l4OffBytes */
200     netTest_UDP_HEADER_LEN,                                                                            /* l4HdrLen */
201     0,                                                                                                  /* pseudoHdrChecksum */
202     0                                                                                                   /* pLoadLen */
203 };
205 nwalTxPktInfo_t txPktInfoNoCrypto = 
207     NULL,                                                                                               /* p_pkt */
208     NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID,      /* txFlags */
209     0,                                                                                                  /* lpbackPass */
210     0,                                                                                                  /* enetport */
211     0,                                                                                                  /* msuSize */
212     0,                                                                                                   /* startOffset */
213     0,                                                    /* saOffBytes */
214     0,                                                                                                  /* saPayLoadLen */
215     0               ,                                                                                    /* saAhIcvOffBytes */
216     0,                                                                                                 /* saAhMacSize */
217     0,                                                                                                  /* etherLenOffBytes */
218     netTest_MAC_HEADER_LEN,         /* ipOffBytes */
219     netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN,                                        /* l4OffBytes */
220     netTest_UDP_HEADER_LEN,                                                             /* l4HdrLen */
221     0,                                                                         /* pseudoHdrChecksum */
222     0                                                                                                   /* pLoadLen */
223 };
225 void close_pktio_channels(void)
227     int err;
228     netapi_pktioClose(netcp_tx_chan_no_crypto ,&err);
229     netapi_pktioClose(netcp_tx_chan_esp ,&err);
230     netapi_pktioClose(netcp_tx_chan_ah ,&err);
235 void open_pktio_tx_channels()
237     int err;
238     /* open netcp default  TX channels */
239     netcp_tx_chan_no_crypto= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
240     if (!netcp_tx_chan_no_crypto)
241     {
242         netapi_Log("pktio open TX failed err=%d\n",err);
243         exit(1);
244     }
245     else
246     {
247         if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
248         {
249             PKTIO_CONTROL_T control;
250             control.op = PKTIO_UPDATE_FAST_PATH;
251             PKTIO_CFG_T cfg;
252             cfg.fast_path_cfg.fp_send_option = PKTIO_FP_NO_CRYPTO_NO_CKSUM_PORT;
253             cfg.fast_path_cfg.txPktInfo= &txPktInfoNoCrypto;
254             //netapi_pktioControl(netcp_tx_chan_no_crypto, NULL, &cfg, &control, &err);
255         }
256     }
257     /* open netcp default  TX for ESP packets */
258     netcp_tx_chan_esp= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
259     if (!netcp_tx_chan_esp)
260     {
261         netapi_Log("pktio open TX failed err=%d\n",err);
262         exit(1);
263     }
264     else
265     {
266         if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
267         {
268             PKTIO_CONTROL_T control;
269             control.op = PKTIO_UPDATE_FAST_PATH;
270             PKTIO_CFG_T cfg;
271             cfg.fast_path_cfg.fp_send_option = PKTIO_FP_ESP_PORT;
272             cfg.fast_path_cfg.txPktInfo= &txPktInfoESP;
273             //netapi_pktioControl(netcp_tx_chan_esp, NULL, &cfg, &control, &err);
274         }
275     }
277     /*/* open netcp default  TX for AH packets */
278     netcp_tx_chan_ah= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
279     if (!netcp_tx_chan_ah)
280     {
281         netapi_Log("pktio open TX failed err=%d\n",err);
282         exit(1);
283     }
284     else
285     {
286         if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
287         {
288             PKTIO_CONTROL_T control;
289             control.op = PKTIO_UPDATE_FAST_PATH;
290             PKTIO_CFG_T cfg;
291             cfg.fast_path_cfg.fp_send_option = PKTIO_FP_AH_PORT;
292             cfg.fast_path_cfg.txPktInfo= &txPktInfoAH;
293             //netapi_pktioControl(netcp_tx_chan_ah, NULL, &cfg, &control, &err);
294         }
295     }
301 NETAPI_T worker_nh[TUNE_NETAPI_NUM_CORES];
302 void slow_path_thread(uint32_t thread_num)
304     int err,i;
305     PKTIO_HANDLE_T *rx_chan;
306     PKTIO_HANDLE_T *sb_tx_chan;
307     PKTIO_HANDLE_T *sb_rx_chan;
310     CPU_ZERO( &cpu_set);
311 #ifdef CORTEX_A15
312     for (i = netTestCfg.sp_proc_start[thread_num]; i <= netTestCfg.sp_proc_end[thread_num];i++)
313     {
314         printf("fast_path_thread: setting cpu %d to cpu_set\n", i);
315         CPU_SET( i, &cpu_set);
316     }
317     hplib_utilSetupCore(thread_num, &cpu_set);
318 #else
319     for (i = netTestCfg.sp_proc_start[thread_num]; i <= netTestCfg.sp_proc_end[thread_num];i++)
320     {
321         printf("fast_path_thread: setting cpu %d to cpu_set\n", i);
322         CPU_SET( i, &cpu_set);
323     }
324     hplib_utilSetupCore(thread_num, &cpu_set);
325 #endif
326     worker_nh[thread_num]=netapi_init(NETAPI_CORE_MASTER,NULL);
328     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) worker_nh[thread_num];
330    /* open netcp RX channel */
331     rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg,  &err);
335     netapi_setCookie(worker_nh[thread_num],(void*) (thread_num | NET_TEST_SP_THREAD_MASK));
336       
337     scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],&our_sched_cfg, &err);
338     if (!scheduler[thread_num]) 
339     {
340         netapi_Log("sched create failed for core%d\n",thread_num); 
341         exit(1);
342     }
343       scheduler[thread_num]->config.yield = FALSE;
344       scheduler[thread_num]->config.pollGarbageQ = TRUE;
345       scheduler[thread_num]->config.pollCtrlQ = TRUE;
346             /*********************************************/
347     /**************Entry point into scheduler ****/
348     /*********************************************/
349     netapi_schedRun(scheduler[thread_num], &err);
350     netapi_Log(">net_test: core %d worker thread done\n",thread_num);
352     netapi_pktioClose(rx_chan, &err);
353     netapi_shutdown(worker_nh[thread_num]);
357 void fast_path_thread(uint32_t thread_num)
359     int err,i;
360     PKTIO_HANDLE_T *rx_chan;
361     PKTIO_HANDLE_T *sb_tx_chan;
362     //PKTIO_HANDLE_T *sb_rx_chan;
364 #ifdef CORTEX_A15
365     for (i = netTestCfg.fp_proc_start[thread_num]; i <= netTestCfg.fp_proc_end[thread_num];i++)
366     {
367         printf("fast_path_thread: setting cpu %d to cpu_set\n", i);
368         CPU_SET( i, &cpu_set);
369     }
370     hplib_utilSetupCore(thread_num, &cpu_set);
371 #else
372     for (i = netTestCfg.fp_proc_start[thread_num]; i <= netTestCfg.fp_proc_end[thread_num];i++)
373     {
374         printf("fast_path_thread: setting cpu %d to cpu_set\n", i);
375         CPU_SET( i, &cpu_set);
376     }
377     hplib_utilSetupCore(thread_num, &cpu_set);
378 #endif
379     worker_nh[thread_num]=netapi_init(NETAPI_CORE_MASTER,NULL);
381     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) worker_nh[thread_num];
383    /* open netcp RX channel */
384     rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg,  &err);
385     netapi_setCookie(worker_nh[thread_num],(void*)thread_num);
387     scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],&our_sched_cfg, &err);
388     if (!scheduler[thread_num]) 
389         {
390         netapi_Log("sched create failed for core%d\n",thread_num); 
391         exit(1);
392     }
394     /*********************************************/
395     /**************Entry point into scheduler ****/
396     /*********************************************/
397     scheduler[thread_num]->config.yield = FALSE;
398      scheduler[thread_num]->config.pollGarbageQ = FALSE;
399      scheduler[thread_num]->config.pollCtrlQ = FALSE;
400      //sleep(100000);
401     netapi_schedRun(scheduler[thread_num], &err);
402     netapi_Log(">net_test: core %d worker thread done\n",thread_num);
404     netapi_pktioClose(rx_chan, &err);
405     netapi_shutdown(worker_nh[thread_num]);
406 \r}
408 #endif
410 /***************************************
411  ********** test driver*****************
412  ***************************************/
413 int main(int argc, char **argv)
415     int err,i;
416     Pktlib_HeapCfg      heapCfg;
417     int32_t             errCode;
418     Pktlib_HeapIfTable*  pPktifTable;
419     FILE * fpr = NULL;
421     /* install signal handler for ^c */
422     signal(SIGINT,netTest_utilMySig);
424     if (argc == 2)
425     {
426         fpr = fopen(argv[1], "r");
427     }
428     else
429     {
430         fpr = fopen(input_file_name, "r");
431     }
432     if (fpr == NULL)
433     {
434         exit(1);
435     }
436     else
437     {
438         memset(&config_file, 0, sizeof(netTestConfigFile_t));
439         memset(&netTestCfg, 0, sizeof(netTestConfig_t));
440         netTest_utilProcessConfigFile(fpr,&config_file);
441         netTest_utilParseMac(&config_file);
443         /* parse slow path/fast path thread configuration parameters */
444         netTest_utilParseThreadParams(&config_file);
446         netTest_utilParseIP(&config_file);
448         netTest_utilParseIpsecMode(&config_file);
450         /* DSP mac processing */
451         parse_dsp_mac(&config_file.dsp_mac[0]);
453        /* DSP IP processing */
454         parse_dsp_ip(&config_file.dsp_ip[0]);
456         netTest_utilParseRoutes(&config_file, &routes[0], &our_router);
457         
458         /* IPSEC interface number processing */
459         parse_simple_param_u32((char*)&config_file.ipsec_if_no[0], &netTestCfg.ipsec_if_no);
461         netTest_utilParseSA(&config_file);
462     }
464     memset(&sa_info, 0, sizeof(sa_info));
466 #ifdef netTest_MULTI_THREAD
467     /* assign main net_test thread to run on core 0 */
468     CPU_ZERO( &cpu_set);
469     CPU_SET( 0, &cpu_set);
470     hplib_utilSetupCore(0, &cpu_set);
471 #endif
472     /* create netapi */
473     netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);
475     /* configure expection packet handling with netapi */
476     netapi_netcpCfgExceptions(netapi_handle, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_DISCARD, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
477     expPkt_appid = netapi_netcpCfgExceptions(netapi_handle, 7, NETCP_CFG_ACTION_TO_SW, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
479     /* open the main heap */
480     ourHeap = Pktlib_findHeapByName("netapi");
481     if (!ourHeap)
482     {
483         netapi_Log("Pktlib_findHeapByName()  fail\n");
484         exit(1);
485     }
487     /* Open all required PKTIO TX channels */
488     open_pktio_tx_channels();
490     netapi_Log("net_test> %d bytes left in our CMA area\n", netapi_getBufMemRemainder());
491     /* create scheduler instance */
492     our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
493     if (!our_sched) {netapi_Log("sched create failed\n"); exit(1);}
496     /*create net_test MAC interfaces, attach IP to created MAC interfaces */
497     netTest_utilCreateInterfaces(netTestCfg.num_macs, netTestCfg.num_ips);
499     /* Lookup Database for SA context, this is used by packet processing routines to get RX and TX SA information*/
500     p_trie_sa_rx = trie_new();
501     p_trie_sa_tx = trie_new();
502    if (!p_trie_sa_rx || !p_trie_sa_tx)
503         {netapi_Log("trie alloc for SA  failed\n"); exit(1);}
505     /* Create RX SA's, RX Policy and TX SA's, all SA configuration parameters are read from net_test_config.txt file */
506     netTest_utilCreateSecAssoc();
509 #ifdef netTest_MULTI_THREAD
511     char c;
512     /* create and set affinity of slow path and fast path threads to
513     * specific CPU cores as specified in the net_test_config.txt file */
514      netTest_utilCreateSpFpThreads(netTestCfg.num_sp_threads, 
515                                   (NET_TEST_FUNC_PTR) slow_path_thread,
516                                   netTestCfg.num_fp_threads,
517                                   (NET_TEST_FUNC_PTR) fast_path_thread);
519         //this thread of execution (main) now just waits on user input
520         for(;;)
521         {
522            printf(">");
523            c=getchar();
524            if (c=='q') {QUIT=1;break;}
525            else if (c=='s') netTest_utilsStatsCb(netapi_handle, &netcp_stats);
526            else if (c=='h') printf("'q' to quit,  's' for stats, 'h' for help\n");
527         }
528         netTest_utilRemoveSpFpThreads(netTestCfg.num_sp_threads, netTestCfg.num_fp_threads);
530 #else
531     /*********************************************/
532     /**************Entry point into scheduler ****/
533     /*********************************************/
534     netapi_schedRun(our_sched, &err);
535 #endif
537 /* done */
538 netTest_utilsStatsCb(netapi_handle, NULL);
542     /* cleanup*/
543     netTest_utilDeleteSecAssoc();
544     netTest_utilDeleteInterfaces(netTestCfg.num_macs, netTestCfg.num_ips);
546     /* close pktio channels we opened via open_pktio_tx_channels() */
547     close_pktio_channels();
550 static inline void send_it(Ti_Pkt *tip, int len, netTestSA_t * p_sec, int out_port)
552   unsigned long st1;
553   unsigned long st2;
554   int err=0;
555   PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
556   nwalTxPktInfo_t meta_tx2={0};
557   st1=hplib_mUtilGetPmuCCNT();
558 #ifdef netTest_MULTI_THREAD
559     int coreid=Osal_nwalGetProcId();  //who we are(thread local)
560     //int coreid = our_core;
561 #else
562     int coreid=0;
563 #endif
564   if (len<60) 
565   { 
566      unsigned int templen;
567      char * p_pkt;
568      len=60; 
569      Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
570      Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
571      stats[coreid].tx_min+=1;
572   }
573   Pktlib_setPacketLen(tip,len);
574   meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
575   meta_tx2.startOffset = 0;
576   meta_tx2.ipOffBytes = netTest_MAC_HEADER_LEN;
577   meta_tx2.ploadLen = len ;
578   meta_tx2.enetPort=out_port;
579   if(p_sec)
580   {   
581        meta_tx2.txFlag1 |= NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO ;
582        //meta2.sa_handle = (void*)p_sec->tx_tunnel;
583        meta2.sa_handle=p_sec->tx_inflow_mode_handle;
584        meta_tx2.saOffBytes=netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN;
585        meta_tx2.saPayloadLen=len-netTest_MAC_HEADER_LEN - netTest_IP_HEADER_LEN;   //don't include tag, mac and outer header
586        meta2.u.tx_meta=&meta_tx2;
587        netapi_pktioSend(netcp_tx_chan_esp,tip,&meta2,&err);
588        stats[coreid].sec_tx+=1;
589   }
590   else
591   {
592       meta2.u.tx_meta=&meta_tx2;
593       netapi_pktioSend(netcp_tx_chan_no_crypto,tip,&meta2,&err);
595   }
596   stats[coreid].tx +=1;
597   st2=hplib_mUtilGetPmuCCNT();
598   stats[coreid].send_cycles += (unsigned long long) (st2-st1);  
599
600 void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
601                          PKTIO_METADATA_T meta[], int n_pkts,
602                          uint64_t ts )
604     int i;
605     int len;
606     int p;
607     Ti_Pkt * tip;
608     unsigned int templen;
609     char * p_pkt;
610     netTestHead_T temp_head;
611     unsigned int appid;
612     IP_netTestHead_T th;
613     netTestSA_t *sec_data=NULL;
614     unsigned long t1;
615     unsigned long t2;
616     unsigned long long ct1;
617     unsigned long long ct2;
618     unsigned short ip_pl;
619     unsigned long long n_c_ops;
620     int ifno;
621     int out_port;
622 #ifdef netTest_MULTI_THREAD
623         int coreid=Osal_nwalGetProcId();  //who we are(thread local)
624         //int coreid = our_core;
625 #else
626     int coreid=0;
627 #endif
628     t1=hplib_mUtilGetPmuCCNT();
629     ct1 =Osal_cache_op_measure(&n_c_ops);
630     for(i=0;i<n_pkts;i++)
631     {
632         ifno = ((unsigned int)meta[i].u.rx_meta->appId)&0xff;
633         if(coreid<TUNE_NETAPI_NUM_CORES) stats[coreid].rx+=1;
634         if (ifno < TUNE_NETAPI_MAX_NUM_MAC) stats[coreid].if_rx[ifno]+=1;
635         tip = p_recv[i];
636         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
637         len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
638         stats[coreid].rx+=1;
639         appid = ((unsigned int)meta[i].u.rx_meta->appId)&0xff000000;
640         switch(appid)
641         {
642            case(NETAPI_NETCP_MATCH_IPSEC):
643            case(NETAPI_NETCP_MATCH_IPSEC_POLICY):
644            {
645              int tailen=12+2;
646              memcpy(&temp_head,&p_pkt[14],sizeof(netTestHead_T));
647              if (!netTest_utilCheckHeader(&temp_head,&meta[i])) {
648                 stats[coreid].n_bad+=1;
649                 Pktlib_freePacket(tip); 
650                 continue;
651              }
652              tailen+=p_pkt[len-12-2]; //padding length  (12)should come from sec_ptr
653              p_pkt = &p_pkt[8+16+20];   //16= iv len, should come from sec_ptr
654              len -= (8+16+20+tailen);  //16= iv len should come from sec ptr
655             
656              //now check inner headder.
657              memcpy(&th,&p_pkt[14],20);
658              if (!netTest_utilCheckHeader(&temp_head,&meta[i])) {
659                 stats[coreid].n_bad+=1;
660                 Pktlib_freePacket(tip);
661                 continue;
662              }
663              Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
664              Pktlib_setPacketLen(tip,len);
665              
666              if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data,&out_port)<0)
667               {
668                 stats[coreid].n_bad+=1;
669                 Pktlib_freePacket(tip);
670              }
671              else
672              {
673                send_it(tip,len,sec_data,out_port);
674              }
675              break;
676            }
677            case(NETAPI_NETCP_MATCH_GENERIC_MAC):
678               if((p_pkt[12]!=0x8)||(p_pkt[13]!=0x00)) 
679               {
680                 stats[coreid].n_new+=1;
681                 Pktlib_freePacket(tip); 
682                 continue;
683               }
684               if (!netTest_utilCheckHeader(&temp_head,&meta[i])) 
685               {
686                 stats[coreid].n_bad+=1;
687                 Pktlib_freePacket(tip);
688                 continue;
689               }
690               memcpy(&th,&p_pkt[14],20);
691               ip_pl= (((unsigned char *)&th.w1)[2]<<8) | ((unsigned char *)&th.w1)[3];
692               if ((ip_pl+14)<60)
693               {
694                 len-= (60-(ip_pl+14));
695                 stats[coreid].rx_min+=1;
696               }
697               Pktlib_setPacketLen(tip,len);
698               if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data,&out_port)<0)
699               {
700                 stats[coreid].n_bad+=1;
701                 Pktlib_freePacket(tip);
702               }
703               else
704               {
705                  send_it(tip,len,sec_data,out_port);
706               }
707               break;
708            case(NETAPI_NETCP_MATCH_GENERIC_IP):
709               Pktlib_freePacket(tip); 
710               stats[coreid].n_new=1;
711               break;
712            default:
713               stats[coreid].n_new+=1;
714               Pktlib_freePacket(tip);
715               break;
716        }
718 t2=hplib_mUtilGetPmuCCNT();
719 ct2 =Osal_cache_op_measure(&n_c_ops);
720 stats[coreid].app_cycles +=  (unsigned long long) (t2-t1);
721 stats[coreid].tx_cache_cycles += (unsigned long long) (ct2-ct1);
722 return;
725 /* STUB functions required for compilation */
726 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
727                          PKTIO_METADATA_T meta[], int n_pkts,
728                          uint64_t ts )
732 void recv_sb_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
733                          PKTIO_METADATA_T meta[], int n_pkts,
734                          uint64_t ts )