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