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