13dd1f42b87da22e9b826952b7c0eb8a1929fba2
[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 <stdio.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <string.h>
48 #include <signal.h>
49 #include <pthread.h>
51 #include "net_test.h"
52 #include "trie.h"
53 #include "string.h"
55 #include <sys/resource.h>
57 #include <ti/drv/sa/salld.h>
58 #include <ti/drv/pa/pa.h>
60 #include "net_test_utils.h"
62 extern int QUIT;
64 /* Global definitions */
65 #ifdef MULTI_THREAD
66     cpu_set_t cpu_set;
67 #endif
69 netTestConfig_t netTestCfg;
70 static  netTestConfigFile_t config_file;
72 char    input_file_name[] = "net_test_config.txt";
74 nwal_RetValue       nwalRetVal;
75 Pktlib_HeapHandle ourHeap;
77 PKTIO_HANDLE_T *netcp_tx_chan_no_crypto;
78 PKTIO_HANDLE_T *netcp_rx_chan;
79 PKTIO_HANDLE_T *netcp_tx_chan_esp;
80 PKTIO_HANDLE_T *netcp_tx_chan_ah;
85 PKTIO_CFG_T netcp_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};
86 PKTIO_CFG_T netcp_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};
90 NETCP_CFG_EXCEPTION_PKT_T expPkt_appid;
92 Trie *p_trie_sa_rx;
93 Trie *p_trie_sa_tx;
96 #include "router.c"
97 extern Trie * our_router;
98 extern OUR_ROUTE_T routes[];
100 unsigned int ip[MAX_ROUTES]={BE(0x0a0100c8),BE(0x0a00000a),BE(0x0a02000a),BE(0xc0a8010a),BE(0x9eda6719)};
102 void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
103                          PKTIO_METADATA_T meta[], int n_pkts,
104                          uint64_t ts );
107 extern STATS_T stats[TUNE_NETAPI_NUM_CORES];
108 extern paSysStats_t netcp_stats;
110 /*******************************************
111  *************NETAPI OBJECTS***************
112  *****************************************/
113 static NETAPI_CFG_T our_netapi_default_cfg=
115 TUNE_NETAPI_PERM_MEM_SZ,
116 128,  //start of packet offset for hw to place data on rx for default flow
117 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
118 TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
119 TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
120 64, //#descriptors w/o buffers in default heap
121 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
122 128   ,  //tail room
123 256      //extra room 
124 };
128 void house(NETAPI_SCHED_HANDLE_T *s);
129 NETAPI_T netapi_handle;
130 NETAPI_SCHED_HANDLE_T * our_sched;
131 #ifdef MULTI_THREAD
132 NETAPI_SCHED_HANDLE_T * scheduler[TUNE_NETAPI_NUM_CORES];
133 #endif
134 NETAPI_SCHED_CONFIG_T our_sched_cfg={
135   NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000  //every 5000000 poll loops
136 };
139 NETCP_CFG_IP_T ip_rule[NET_TEST_MAX_IP];
140 NETCP_CFG_MACIF_T mac[NET_TEST_MAX_MAC];
144 /* security objects. (for loopback mode) */
145 netTestSA_t sa_info[MAX_SEC_INDEX];
148 NETCP_CFG_IPSEC_POLICY_T rx_policy[MAX_SEC_INDEX];
153 /*************************END NETAPI OBJECTS***********************/
155 void update_header(HEAD_T * p_head, int len)
157    unsigned char *p = (unsigned char *) &p_head->udp[1];
158    len -= (20+14);
159    /* update ip checksum */
160    /* update udp checksum */
161    /* update length */
162    *p= (len&0xff00)>>8;
163    *(p+1) = len&0xff;
166 #ifdef MULTI_THREAD
167 /* Templates to build command labels at startup up time, required by open_pktio_tx_channels() */
168 nwalTxPktInfo_t txPktInfoESP = 
170     NULL,                                                                                               /* p_pkt */
171     NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID,      /* txFlags */
172     0,                                                                                                  /* lpbackPass */
173     1,                                                                                                  /* enetport */
174     0,                                                                                                  /* msuSize */
175     0,                                                                                                   /* startOffset */
176     netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN,                                                    /* saOffBytes */
177     0,                                                                                                  /* saPayLoadLen */
178     0               ,                                                                                    /* saAhIcvOffBytes */
179     0,                                                                                                 /* saAhMacSize */
180     0,                                                                                                  /* etherLenOffBytes */
181     netTest_MAC_HEADER_LEN,                                                        /* ipOffBytes */
182     0,                                                                                                  /* l4OffBytes */
183     0,                         /* l4HdrLen */
184     0,                                                                                   /* pseudoHdrChecksum */
185     0                                                                                                   /* pLoadLen */
186 };
189 nwalTxPktInfo_t txPktInfoAH = 
191     NULL,                                                                                               /* p_pkt */
192     NWAL_TX_FLAG1_DO_IPSEC_AH_CRYPTO| NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_META_DATA_VALID,      /* txFlags */
193     0,                                                                                                  /* lpbackPass */
194     0,                                                                                                  /* enetport */
195     0,                                                                                                  /* msuSize */
196     0,                                                                                                   /* startOffset */
197     netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN,                                                    /* saOffBytes */
198     0,                                                                                                  /* saPayLoadLen */
199     netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN + netTest_IPSEC_AH_FIXED_HDR_SIZE,                    /* saAhIcvOffBytes */
200     12,                                                                                                 /* saAhMacSize */
201     0,                                                                                                  /* etherLenOffBytes */
202     netTest_MAC_HEADER_LEN,   /* ipOffBytes */
203     0,                                                                                                  /* l4OffBytes */
204     netTest_UDP_HEADER_LEN,                                                                            /* l4HdrLen */
205     0,                                                                                                  /* pseudoHdrChecksum */
206     0                                                                                                   /* pLoadLen */
207 };
209 nwalTxPktInfo_t txPktInfoNoCrypto = 
211     NULL,                                                                                               /* p_pkt */
212     NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID,      /* txFlags */
213     0,                                                                                                  /* lpbackPass */
214     0,                                                                                                  /* enetport */
215     0,                                                                                                  /* msuSize */
216     0,                                                                                                   /* startOffset */
217     0,                                                    /* saOffBytes */
218     0,                                                                                                  /* saPayLoadLen */
219     0               ,                                                                                    /* saAhIcvOffBytes */
220     0,                                                                                                 /* saAhMacSize */
221     0,                                                                                                  /* etherLenOffBytes */
222     netTest_MAC_HEADER_LEN,         /* ipOffBytes */
223     netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN,                                        /* l4OffBytes */
224     netTest_UDP_HEADER_LEN,                                                             /* l4HdrLen */
225     0,                                                                         /* pseudoHdrChecksum */
226     0                                                                                                   /* pLoadLen */
227 };
229 void close_pktio_channels(void)
231     int err;
232     netapi_pktioClose(netcp_tx_chan_no_crypto ,&err);
233     netapi_pktioClose(netcp_tx_chan_esp ,&err);
234     netapi_pktioClose(netcp_tx_chan_ah ,&err);
239 void open_pktio_tx_channels()
241     int err;
242     /* open netcp default  TX channels */
243     netcp_tx_chan_no_crypto= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
244     if (!netcp_tx_chan_no_crypto)
245     {
246         netapi_Log("pktio open TX failed err=%d\n",err);
247         exit(1);
248     }
249     else
250     {
251         if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
252         {
253             PKTIO_CONTROL_T control;
254             control.op = PKTIO_UPDATE_FAST_PATH;
255             PKTIO_CFG_T cfg;
256             cfg.fast_path_cfg.fp_send_option = PKTIO_FP_NO_CRYPTO_NO_CKSUM_PORT;
257             cfg.fast_path_cfg.txPktInfo= &txPktInfoNoCrypto;
258             //netapi_pktioControl(netcp_tx_chan_no_crypto, NULL, &cfg, &control, &err);
259         }
260     }
261     /* open netcp default  TX for ESP packets */
262     netcp_tx_chan_esp= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
263     if (!netcp_tx_chan_esp)
264     {
265         netapi_Log("pktio open TX failed err=%d\n",err);
266         exit(1);
267     }
268     else
269     {
270         if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
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_ESP_PORT;
276             cfg.fast_path_cfg.txPktInfo= &txPktInfoESP;
277             //netapi_pktioControl(netcp_tx_chan_esp, NULL, &cfg, &control, &err);
278         }
279     }
281     /*/* open netcp default  TX for AH packets */
282     netcp_tx_chan_ah= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
283     if (!netcp_tx_chan_ah)
284     {
285         netapi_Log("pktio open TX failed err=%d\n",err);
286         exit(1);
287     }
288     else
289     {
290         if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
291         {
292             PKTIO_CONTROL_T control;
293             control.op = PKTIO_UPDATE_FAST_PATH;
294             PKTIO_CFG_T cfg;
295             cfg.fast_path_cfg.fp_send_option = PKTIO_FP_AH_PORT;
296             cfg.fast_path_cfg.txPktInfo= &txPktInfoAH;
297             //netapi_pktioControl(netcp_tx_chan_ah, NULL, &cfg, &control, &err);
298         }
299     }
305 NETAPI_T worker_nh[TUNE_NETAPI_NUM_CORES];
306 void slow_path_thread(uint32_t thread_num)
308     int err,i;
309     PKTIO_HANDLE_T *rx_chan;
310     PKTIO_HANDLE_T *sb_tx_chan;
311     PKTIO_HANDLE_T *sb_rx_chan;
314     CPU_ZERO( &cpu_set);
315 #ifdef CORTEX_A15
316     for (i = netTestCfg.sp_proc_start[thread_num]; i <= netTestCfg.sp_proc_end[thread_num];i++)
317     {
318         printf("fast_path_thread: setting cpu %d to cpu_set\n", i);
319         CPU_SET( i, &cpu_set);
320     }
321     hplib_utilSetupCore(thread_num, &cpu_set);
322 #else
323     for (i = netTestCfg.sp_proc_start[thread_num]; i <= netTestCfg.sp_proc_end[thread_num];i++)
324     {
325         printf("fast_path_thread: setting cpu %d to cpu_set\n", i);
326         CPU_SET( i, &cpu_set);
327     }
328     hplib_utilSetupCore(thread_num, &cpu_set);
329 #endif
330     worker_nh[thread_num]=netapi_init(NETAPI_CORE_MASTER,NULL);
332     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) worker_nh[thread_num];
334    /* open netcp RX channel */
335     rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg,  &err);
339     netapi_setCookie(worker_nh[thread_num],(void*) (thread_num | NET_TEST_SP_THREAD_MASK));
340       
341     scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],&our_sched_cfg, &err);
342     if (!scheduler[thread_num]) 
343     {
344         netapi_Log("sched create failed for core%d\n",thread_num); 
345         exit(1);
346     }
347       scheduler[thread_num]->config.yield = FALSE;
348       scheduler[thread_num]->config.pollGarbageQ = TRUE;
349       scheduler[thread_num]->config.pollCtrlQ = TRUE;
350             /*********************************************/
351     /**************Entry point into scheduler ****/
352     /*********************************************/
353     netapi_schedRun(scheduler[thread_num], &err);
354     netapi_Log(">net_test: core %d worker thread done\n",thread_num);
356     netapi_pktioClose(rx_chan, &err);
357     netapi_shutdown(worker_nh[thread_num]);
361 void fast_path_thread(uint32_t thread_num)
363     int err,i;
364     PKTIO_HANDLE_T *rx_chan;
365     PKTIO_HANDLE_T *sb_tx_chan;
366     //PKTIO_HANDLE_T *sb_rx_chan;
368 #ifdef CORTEX_A15
369     for (i = netTestCfg.fp_proc_start[thread_num]; i <= netTestCfg.fp_proc_end[thread_num];i++)
370     {
371         printf("fast_path_thread: setting cpu %d to cpu_set\n", i);
372         CPU_SET( i, &cpu_set);
373     }
374     hplib_utilSetupCore(thread_num, &cpu_set);
375 #else
376     for (i = netTestCfg.fp_proc_start[thread_num]; i <= netTestCfg.fp_proc_end[thread_num];i++)
377     {
378         printf("fast_path_thread: setting cpu %d to cpu_set\n", i);
379         CPU_SET( i, &cpu_set);
380     }
381     hplib_utilSetupCore(thread_num, &cpu_set);
382 #endif
383     worker_nh[thread_num]=netapi_init(NETAPI_CORE_MASTER,NULL);
385     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) worker_nh[thread_num];
387    /* open netcp RX channel */
388     rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg,  &err);
389     netapi_setCookie(worker_nh[thread_num],(void*)thread_num);
391     scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],&our_sched_cfg, &err);
392     if (!scheduler[thread_num]) 
393         {
394         netapi_Log("sched create failed for core%d\n",thread_num); 
395         exit(1);
396     }
398     /*********************************************/
399     /**************Entry point into scheduler ****/
400     /*********************************************/
401     scheduler[thread_num]->config.yield = FALSE;
402      scheduler[thread_num]->config.pollGarbageQ = FALSE;
403      scheduler[thread_num]->config.pollCtrlQ = FALSE;
404      //sleep(100000);
405     netapi_schedRun(scheduler[thread_num], &err);
406     netapi_Log(">net_test: core %d worker thread done\n",thread_num);
408     netapi_pktioClose(rx_chan, &err);
409     netapi_shutdown(worker_nh[thread_num]);
410 \r}
412 #endif
414 /***************************************
415  ********** test driver*****************
416  ***************************************/
417 int main(int argc, char **argv)
419     int err,i;
420     Pktlib_HeapCfg      heapCfg;
421     rlim_t oss,ss = 1024*1024;
422     struct rlimit rl;
423     int32_t             errCode;
424     Pktlib_HeapIfTable*  pPktifTable;
425 /* Local Per Process default resourcese maintained at NWAL */
426     nwalLocCxtInfo_t    nwalLocCxt;
428     FILE * fpr = NULL;
431     err= getrlimit(RLIMIT_STACK,&rl);
432     if (!err) netapi_Log(" stack limit = %d\n",rl.rlim_cur); else netapi_Log("getrlimit failed\n");
434      /* install signal handler for ^c */
435     signal(SIGINT,mysig);
437     if (argc == 2)
438     {
439         fpr = fopen(argv[1], "r");
440     }
441     else
442     {
443         fpr = fopen(input_file_name, "r");
444     }
445     if (fpr == NULL)
446     {
447         exit(1);
448     }
449     else
450     {
451         memset(&config_file, 0, sizeof(netTestConfigFile_t));
452         memset(&netTestCfg, 0, sizeof(netTestConfig_t));
453         parse_config_file(fpr,&config_file);
454     }
456     memset(&sa_info, 0, sizeof(sa_info));
458 #ifdef MULTI_THREAD
459     /* assign main net_test thread to run on core 0 */
460     CPU_ZERO( &cpu_set);
461     CPU_SET( 0, &cpu_set);
462     hplib_utilSetupCore(0, &cpu_set);
463 #endif
464     /* create netapi */
465     netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);
467     /* configure expection packet handling with netapi */
468     netapi_netcpCfgExceptions(netapi_handle, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_DISCARD, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
469     expPkt_appid = netapi_netcpCfgExceptions(netapi_handle, 7, NETCP_CFG_ACTION_TO_SW, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
471     /* open the main heap */
472     ourHeap = Pktlib_findHeapByName("netapi");
473     if (!ourHeap)
474     {
475         netapi_Log("Pktlib_findHeapByName()  fail\n");
476         exit(1);
477     }
479     /* Open all required PKTIO TX channels */
480     open_pktio_tx_channels();
482     netapi_Log("net_test> %d bytes left in our CMA area\n", netapi_getBufMemRemainder());
483     /* create scheduler instance */
484     our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
485     if (!our_sched) {netapi_Log("sched create failed\n"); exit(1);}
488     /*create net_test MAC interfaces, attach IP to created MAC interfaces */
489      create_interfaces();
491     /* Lookup Database for SA context, this is used by packet processing routines to get RX and TX SA information*/
492     p_trie_sa_rx = trie_new();
493     p_trie_sa_tx = trie_new();
494    if (!p_trie_sa_rx || !p_trie_sa_tx)
495         {netapi_Log("trie alloc for SA  failed\n"); exit(1);}
497     /* Create RX SA's, RX Policy and TX SA's, all SA configuration parameters are read from net_test_config.txt file */
498     create_sec_associations();
501 #ifdef MULTI_THREAD
503     char c;
504     /* create and set affinity of slow path and fast path threads to
505     * specific CPU cores as specified in the net_test_config.txt file */
506     create_sp_fp_threads();
509         //this thread of execution (main) now just waits on user input
510         for(;;)
511         {
512            printf(">");
513            c=getchar();
514            if (c=='q') {QUIT=1;break;}
515            else if (c=='s') our_stats_cb(netapi_handle, &netcp_stats);
516            else if (c=='h') printf("'q' to quit,  's' for stats, 'h' for help\n");
517         }
520 #else
521     /*********************************************/
522     /**************Entry point into scheduler ****/
523     /*********************************************/
524     netapi_schedRun(our_sched, &err);
525 #endif
527 /* done */
528 our_stats_cb(netapi_handle, NULL);
532     /* cleanup*/
533     delete_sec_associations();
534     delete_interfaces();
536     /* close pktio channels we opened via open_pktio_tx_channels() */
537     close_pktio_channels();
540 static inline void send_it(Ti_Pkt *tip, int len, ROUTE_SEC_T * p_sec, int out_port)
542   unsigned long st1;
543   unsigned long st2;
544   int err=0;
545   PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
546   nwalTxPktInfo_t meta_tx2={0};
547   st1=hplib_mUtilGetPmuCCNT();
548 #ifdef MULTI_THREAD
549     int coreid=Osal_nwalGetProcId();  //who we are(thread local)
550     //int coreid = our_core;
551 #else
552     int coreid=0;
553 #endif
554   if (len<60) 
555   { 
556      unsigned int templen;
557      char * p_pkt;
558      len=60; 
559      Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
560      Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
561      stats[coreid].tx_min+=1;
562   }
563   Pktlib_setPacketLen(tip,len);
564   meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
565   meta_tx2.startOffset = 0;
566   meta_tx2.ipOffBytes = netTest_MAC_HEADER_LEN;
567   meta_tx2.ploadLen = len ;
568   meta_tx2.enetPort=out_port;
569   if(p_sec)
570   {   
571        meta_tx2.txFlag1 |= NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO ;
572        //meta2.sa_handle = (void*)p_sec->tx_tunnel;
573        meta2.sa_handle=p_sec->tx_inflow_mode_handle;
574        meta_tx2.saOffBytes=netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN;
575        meta_tx2.saPayloadLen=len-netTest_MAC_HEADER_LEN - netTest_IP_HEADER_LEN;   //don't include tag, mac and outer header
576        meta2.u.tx_meta=&meta_tx2;
577        pktio_send(netcp_tx_chan_esp,tip,&meta2,&err);
578        stats[coreid].sec_tx+=1;
579   }
580   else
581   {
582       meta2.u.tx_meta=&meta_tx2;
583       pktio_send(netcp_tx_chan_no_crypto,tip,&meta2,&err);
585   }
586   stats[coreid].tx +=1;
587   st2=hplib_mUtilGetPmuCCNT();
588   stats[coreid].send_cycles += (unsigned long long) (st2-st1);  
589
590 void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
591                          PKTIO_METADATA_T meta[], int n_pkts,
592                          uint64_t ts )
594     int i;
595     int len;
596     int p;
597     Ti_Pkt * tip;
598     unsigned int templen;
599     char * p_pkt;
600     HEAD_T temp_head;
601     unsigned int appid;
602     IP_HEAD_T th;
603     ROUTE_SEC_T *sec_data=NULL;
604     unsigned long t1;
605     unsigned long t2;
606     unsigned long long ct1;
607     unsigned long long ct2;
608     unsigned short ip_pl;
609     unsigned long long n_c_ops;
610     int ifno;
611     int out_port;
612 #ifdef MULTI_THREAD
613         int coreid=Osal_nwalGetProcId();  //who we are(thread local)
614         //int coreid = our_core;
615 #else
616     int coreid=0;
617 #endif
618     t1=hplib_mUtilGetPmuCCNT();
619     ct1 =Osal_cache_op_measure(&n_c_ops);
620     for(i=0;i<n_pkts;i++)
621     {
622         ifno = ((unsigned int)meta[i].u.rx_meta->appId)&0xff;
623         if(coreid<TUNE_NETAPI_NUM_CORES) stats[coreid].rx+=1;
624         if (ifno < TUNE_NETAPI_MAX_NUM_MAC) stats[coreid].if_rx[ifno]+=1;
625         tip = p_recv[i];
626         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
627         len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
628         stats[coreid].rx+=1;
629         appid = ((unsigned int)meta[i].u.rx_meta->appId)&0xff000000;
630         switch(appid)
631         {
632            case(NETAPI_NETCP_MATCH_IPSEC):
633            case(NETAPI_NETCP_MATCH_IPSEC_POLICY):
634            {
635              int tailen=12+2;
636              memcpy(&temp_head,&p_pkt[14],sizeof(HEAD_T));
637              if (!check_header(&temp_head,&meta[i])) {
638                 stats[coreid].n_bad+=1;
639                 Pktlib_freePacket(tip); 
640                 continue;
641              }
642              tailen+=p_pkt[len-12-2]; //padding length  (12)should come from sec_ptr
643              p_pkt = &p_pkt[8+16+20];   //16= iv len, should come from sec_ptr
644              len -= (8+16+20+tailen);  //16= iv len should come from sec ptr
645             
646              //now check inner headder.
647              memcpy(&th,&p_pkt[14],20);
648              if (!check_header(&temp_head,&meta[i])) {
649                 stats[coreid].n_bad+=1;
650                 Pktlib_freePacket(tip);
651                 continue;
652              }
653              Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
654              Pktlib_setPacketLen(tip,len);
655              
656              if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data,&out_port)<0)
657               {
658                 stats[coreid].n_bad+=1;
659                 Pktlib_freePacket(tip);
660              }
661              else
662              {
663                send_it(tip,len,sec_data,out_port);
664              }
665              break;
666            }
667            case(NETAPI_NETCP_MATCH_GENERIC_MAC):
668               if((p_pkt[12]!=0x8)||(p_pkt[13]!=0x00)) 
669               {
670                 stats[coreid].n_new+=1;
671                 Pktlib_freePacket(tip); 
672                 continue;
673               }
674               if (!check_header(&temp_head,&meta[i])) 
675               {
676                 stats[coreid].n_bad+=1;
677                 Pktlib_freePacket(tip);
678                 continue;
679               }
680               memcpy(&th,&p_pkt[14],20);
681               ip_pl= (((unsigned char *)&th.w1)[2]<<8) | ((unsigned char *)&th.w1)[3];
682               if ((ip_pl+14)<60)
683               {
684                 len-= (60-(ip_pl+14));
685                 stats[coreid].rx_min+=1;
686               }
687               Pktlib_setPacketLen(tip,len);
688               if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data,&out_port)<0)
689               {
690                 stats[coreid].n_bad+=1;
691                 Pktlib_freePacket(tip);
692               }
693               else
694               {
695                  send_it(tip,len,sec_data,out_port);
696               }
697               break;
698            case(NETAPI_NETCP_MATCH_GENERIC_IP):
699               Pktlib_freePacket(tip); 
700               stats[coreid].n_new=1;
701               break;
702            default:
703               stats[coreid].n_new+=1;
704               Pktlib_freePacket(tip);
705               break;
706        }
708 t2=hplib_mUtilGetPmuCCNT();
709 ct2 =Osal_cache_op_measure(&n_c_ops);
710 stats[coreid].app_cycles +=  (unsigned long long) (t2-t1);
711 stats[coreid].tx_cache_cycles += (unsigned long long) (ct2-ct1);
712 return;
715 /* STUB functions required for compilation */
716 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
717                          PKTIO_METADATA_T meta[], int n_pkts,
718                          uint64_t ts )
722 void recv_sb_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
723                          PKTIO_METADATA_T meta[], int n_pkts,
724                          uint64_t ts )