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