7049f46ef8cb9d83bc23f775700803370b512852
[keystone-rtos/netapi.git] / ti / runtime / netapi / test / net_test_loopback.c
1 /******************************************************************************
2  * File: net_test.c
3  * Purpose: test app for netapi
4  ******************************************************************************
5  * FILE:  net_test.c
6  * 
7  * DESCRIPTION:  netapi user space transport
8  *               library  test 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"
48 #include "ti/drv/nwal/test/fw_rm.h"
49 #include <signal.h>
50 #include <pthread.h>
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 /* Device */
71 extern int QUIT;
72 extern netTestStats_T stats[];
73 extern paSysStats_t netcp_stats;
75 extern Rm_ServiceHandle   *rmClientServiceHandle;
76 hplib_spinLock_T net_test_thread_lock;
79 netTestConfig_t netTestCfg;
80 static netTestConfigFile_t config_file;
81 char    input_file_name[] = "/etc/transportnetlib/test/net_test_config.txt";
82 nwal_RetValue       nwalRetVal;
83 Pktlib_HeapHandle   ourHeap;
85 PKTIO_HANDLE_T *netcp_rx_chan;
86 PKTIO_HANDLE_T *netcp_tx_chan_no_crypto;
87 PKTIO_HANDLE_T *netcp_tx_chan_esp;
88 PKTIO_HANDLE_T *netcp_tx_chan_ah;
89 PKTIO_HANDLE_T *netcp_sb_tx_chan;
90 PKTIO_HANDLE_T *netcp_sb_rx_chan;
92 PKTIO_CFG_T netcp_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};
93 PKTIO_CFG_T netcp_rx_cfg2={PKTIO_RX, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8};
94 PKTIO_CFG_T netcp_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};
95 PKTIO_CFG_T netcp_sb_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};
96 PKTIO_CFG_T netcp_sb_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};
98 NETCP_CFG_IP_T ip_rule[NET_TEST_MAX_IP];
99 NETCP_CFG_MACIF_T mac[NET_TEST_MAX_MAC];
101 #ifdef netTest_DSP_FASTPATH
102 PKTIO_HANDLE_T *dsp_pktio_channels[CPU_NUM_REM_FAST_PATH_CORES];
103 NETCP_CFG_CLASS_T dsp_classifers[CPU_NUM_REM_FAST_PATH_CORES];
104 NETCP_CFG_FLOW_HANDLE_T dsp_flow_handles[CPU_NUM_REM_FAST_PATH_CORES];
105 #endif
106 NETCP_CFG_EXCEPTION_PKT_T expPkt_appid;
108 Trie *p_trie_sa_rx;
109 Trie *p_trie_sa_tx;
112 /*******************************************
113  *************NETAPI OBJECTS***************
114  *****************************************/
115 static NETAPI_CFG_T our_netapi_default_cfg=
117     TUNE_NETAPI_PERM_MEM_SZ,
118     128,  //start of packet offset for hw to place data on rx for default flow
119     TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
120     TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
121     TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
122     64, //#descriptors w/o buffers in default heap
123     TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
124     128, //tail room
125     256, //extra room
126     0,
127     NULL,
128     -1,
129     -1
130 };
132 NETAPI_T netapi_handle;
133 NETAPI_SCHED_HANDLE_T * our_sched;
134 #ifdef netTest_MULTI_THREAD
135 NETAPI_SCHED_HANDLE_T * scheduler[TUNE_NETAPI_NUM_CORES];
136 #endif
137 NETAPI_SCHED_CONFIG_T our_sched_cfg={
138   NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000  //every 5000000 poll loops
139 };
141 netTestSA_t sa_info[MAX_SEC_INDEX];
142 NETCP_CFG_IPSEC_POLICY_T rx_policy[MAX_SEC_INDEX];
144 int masterType = NETAPI_SYS_MASTER;
150 /********************************************************************
151  * FUNCTION PURPOSE:  Utility function to flip and packet and send
152  *                    it back to its source.
153  ********************************************************************
154  * DESCRIPTION:   Utility function to flip and packet and send
155  *                    it back to its source.
156  ********************************************************************/
157 void flip_and_send_pkt(Ti_Pkt *tip,  unsigned char * p_pkt, int len, int flag, uint16_t enet_port)
159     unsigned char mac_temp[6];
160     unsigned char ip_temp[4];
161     unsigned char new_dest_port[2]={0x75,0x30};  // 30000
162     uint16_t dest_udp_port_config = 0;
163     uint16_t blah; 
164     uint16_t i=1;   /* for testing only */
166     uint8_t *p_spi; 
167     netTestSA_t * p_sa_info;
168     netTestSA_t *p_sa_info_tx;
169     uint8_t p_iv[16];
170     uint8_t p_add[8];
171     Cppi_HostDesc*          pPloadDesc;
172     uint8_t ah_len;
173     uint32_t tunnel_id;
174     nwalLocCxtInfo_t    nwalLocCxt;
175     netTestHead_T * p_head;
176     netTestHead_T temp_head;
177     int pkt_type;
179 #ifdef netTest_MULTI_THREAD
180     int coreid=Osal_nwalGetProcId(); //who we are(thread local)
181         //int coreid = our_core;
182 #else
183 int coreid=0;
184 #endif
185     // netTest_utilDumpBuffer((long*)p_pkt,len);
186     Pktlib_setPacketLen(tip,len);
187     //flip the mac address
188     memcpy(&mac_temp,&p_pkt[0],6);
189     memcpy(&p_pkt[0],&p_pkt[6],6);
190     memcpy(&p_pkt[6],&mac_temp,6);
191     //memcpy(&p_pkt[0],real_mac_header,6); //for testing to wireshark pc
193     //flip the ip  (outer in case of ipsec)
194     memcpy(&ip_temp, &p_pkt[netTest_MAC_HEADER_LEN+12],4);
195     memcpy(&p_pkt[netTest_MAC_HEADER_LEN+12],&p_pkt[netTest_MAC_HEADER_LEN+12+4],4);
196     memcpy(&p_pkt[netTest_MAC_HEADER_LEN+12+4],&ip_temp,4);
198     p_head=&temp_head;
200     //inner ip &udp for ipsec
201     if (flag) 
202     {
203         memcpy(p_head,&p_pkt[netTest_MAC_HEADER_LEN],sizeof(netTestHead_T));
205         if ((p_head->ip[2]&0x0000ff00)==0x00003300)
206         {
207             p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN + 4]);
208             pkt_type = netTest_IPSEC_AH_PKT;
209         }
210         else if ((p_head->ip[2]&0x0000ff00)==0x00003200)
211         {
212             p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]);
213             pkt_type = netTest_IPSEC_ESP_PKT;
214         }
215         else
216         {
217             netapi_Log("flip_and_send_pkt: un-supported IPSEC protocol\n");
218             Pktlib_freePacket(tip);
219             return;
220         }
222         p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa_rx, (char *)p_spi ,4);
223         if (p_sa_info == NULL)
224         {
225             netapi_Log("flip_and_send_pkt(): trie_lookup() failed\n");
226             Pktlib_freePacket(tip);
227             return;
228         }
229         tunnel_id = p_sa_info->tunnel_id;
230         p_sa_info_tx = (netTestSA_t *) trie_lookup(p_trie_sa_tx, (char *)&tunnel_id ,4);
231         if (p_sa_info_tx == NULL)
232         {
233             netapi_Log("flip_and_send_pkt(): trie_lookup() failed\n");
234             Pktlib_freePacket(tip);
235             return;
236         }
237         //just drop non-udp packet
238         if (p_pkt[p_sa_info->tx_payload_info.encOffset+9]!=0x11)
239         {
240             stats[coreid].n_new+=1;Pktlib_freePacket(tip); return;
241         }
243         /* flip inner IP */
244         memcpy(&ip_temp, &p_pkt[p_sa_info->tx_payload_info.encOffset+12],4);
245         memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+12],&p_pkt[p_sa_info->tx_payload_info.encOffset+12+4],4);
246         memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+12+4],&ip_temp,4);
247         /* setting udp ports */
248         if (netTestCfg.dest_udp_port_config == 0)
249         {
250             memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+netTest_IP_HEADER_LEN+2],
251                    &p_pkt[p_sa_info->tx_payload_info.encOffset+netTest_IP_HEADER_LEN],2);
252         }
253         else
254         {
255            dest_udp_port_config = htons(netTestCfg.dest_udp_port_config);
256             memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+netTest_IP_HEADER_LEN+2],
257                    &dest_udp_port_config,2);
258         }
259         memset(&p_pkt[p_sa_info->tx_payload_info.encOffset+netTest_IP_HEADER_LEN+6],0,2); //checksum
261         if (netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND)
262         {
263             /* inner ip checksum : leave alone, outer ip, set to 0 (we will compute on way out */
264             memset(&p_pkt[netTest_MAC_HEADER_LEN+10],0,2);
265         }
266     }
267     else
268     {
269         /* flip udp port */
270         if (netTestCfg.dest_udp_port_config == 0)
271         {
272             memcpy(&p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+2],
273                    &p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN],2);
274         }
275         else
276         {
277             dest_udp_port_config = htons(netTestCfg.dest_udp_port_config);
278             //memcpy(&p_pkt[netTest_MAC_HEADER_LEN+20+2],&new_dest_port[0],2);
279             memcpy(&p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+2],&dest_udp_port_config,2);
280         }
281         memset(&p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+6],0,2);//0 udp checksum (we will compute on way out)
282     }
284     /*IPSEC case */ 
285     if (flag)
286     {
287         if (netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND)
288         //send to crypto for encryption
289         //12 byte auth tag
290         {
291             PKTIO_METADATA_T meta = {PKTIO_META_SB_TX,{0},0};
292             int err;
293             nwalDmTxPayloadInfo_t meta_tx={0};
294             
295             meta.sa_handle = (void*)p_sa_info_tx->tx_tunnel;  //use TX SA APPID
297             memcpy(&meta_tx, &(p_sa_info->tx_payload_info), sizeof(nwalDmTxPayloadInfo_t));
298             meta_tx.appCtxId = (nwal_AppId)p_sa_info_tx;
299             meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -p_sa_info->auth_tag_size;
300             meta_tx.authSize = len - meta_tx.authOffset - p_sa_info->auth_tag_size;
301             meta_tx.pAuthIV=NULL;
302             meta_tx.aadSize=0;
303             meta_tx.pAad=NULL;
304             if (p_sa_info->cipherMode ==  NWAL_SA_EALG_AES_CTR)
305             {
306                 memcpy(&p_iv[0], &p_sa_info->key_params->pEncKey[16], 4);
307                 memcpy(&p_iv[4], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
308                 p_iv[12] = 0;
309                 p_iv[13] = 0;
310                 p_iv[14] = 0;
311                 p_iv[15] = 1;
312                 meta_tx.pEncIV = &p_iv[0];
313             }
314             else if ((p_sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) || (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CCM))
315             {
316                 memcpy(&p_iv[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
317                 meta_tx.pEncIV = &p_iv[0];
318                 memcpy(&p_add[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN], 8);
319                 meta_tx.pAad= &p_add[0];
320                 meta_tx.aadSize = 8;
321             }
322             else if (p_sa_info->authMode == NWAL_SA_AALG_GMAC)
323             {
324                 memcpy(&p_iv[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
325                 meta_tx.pAuthIV= &p_iv[0];
326                 memcpy(&p_add[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN], 8);
327                 meta_tx.pAad= &p_add[0];
328                 meta_tx.aadSize = 8;
329             }
330             else if (p_sa_info->cipherMode ==  NWAL_SA_EALG_NULL)
331             {
332                 meta_tx.pEncIV = NULL;
333             }
334             else
335             {
336                 meta_tx.pEncIV = &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN ];
337             }
338             /* post it to netcp sb tx channel*/
339             meta.u.tx_sb_meta=&meta_tx;
341             netapi_pktioSend(netcp_sb_tx_chan,tip,&meta,&err);
342         }
343         else
344         {
345             //INFLOW TX, send pkt directly, asking for IP and UDP checksum offloads AND IPSEC to be applied
346             PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};
347             int err;
348             nwalTxPktInfo_t meta_tx={0};
350             meta.sa_handle = (void*)p_sa_info_tx->tx_tunnel;  //use TX SA APPID
352             meta_tx.startOffset = p_sa_info_tx->tx_pkt_info.startOffset;
353             meta_tx.ipOffBytes =p_sa_info_tx->tx_payload_info.encOffset; 
354             meta_tx.l4OffBytes = p_sa_info_tx->tx_pkt_info.l4OffBytes;
355             meta_tx.l4HdrLen = p_sa_info_tx->tx_pkt_info.l4HdrLen;
356             meta_tx.ploadLen = (unsigned) ((p_pkt[meta_tx.l4OffBytes+4]<<8)|p_pkt[meta_tx.l4OffBytes+4+1]) -8 ;
357             meta_tx.saOffBytes=  p_sa_info_tx->tx_pkt_info.saOffBytes;
358             if (pkt_type == netTest_IPSEC_AH_PKT)
359             {
360                 memset(&p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+netTest_IPSEC_AH_FIXED_HDR_SIZE],0,netTest_IPSEC_AH_FIXED_HDR_SIZE);
361                 meta_tx.txFlag1 = p_sa_info_tx->tx_pkt_info.txFlag1;
362                 meta_tx.saPayloadLen=len-netTest_MAC_HEADER_LEN;   //don't inlcude mac 
363                 meta_tx.saAhMacSize = 12;
364                 meta_tx.saAhIcvOffBytes = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN + netTest_IPSEC_AH_FIXED_HDR_SIZE;
365                 
366                 meta_tx.enetPort = enet_port;
367                  memcpy(&p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+4],&p_sa_info_tx->spi,4);
368             }
369             else if (pkt_type == netTest_IPSEC_ESP_PKT)
370             {
371                 meta_tx.txFlag1 = p_sa_info_tx->tx_pkt_info.txFlag1;
372                 meta_tx.saPayloadLen=len-netTest_MAC_HEADER_LEN-netTest_IP_HEADER_LEN;   //don't include mac and ip outer header
373                 meta_tx.enetPort = 0;
374                  memcpy(&p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN],&p_sa_info_tx->spi,4);
375             }
377             meta_tx.pseudoHdrChecksum =
378             netTest_utilGetIPv4PsudoChkSum(&p_pkt[meta_tx.ipOffBytes],8+ meta_tx.ploadLen);
381             /* post it to netcp tx channel*/
382             meta.u.tx_meta=&meta_tx;
383 #ifdef DEBUG_DESC
384             if (stats[coreid].sec_tx<20) netTest_utilDumpDescr((long *) tip, stats[coreid].sec_tx);
385 #endif
386             if ( pkt_type == netTest_IPSEC_ESP_PKT)
387                 netapi_pktioSend(netcp_tx_chan_esp,tip,&meta,&err);
388             else if ( pkt_type == netTest_IPSEC_AH_PKT)
389                  netapi_pktioSend(netcp_tx_chan_ah,tip,&meta,&err);
390             stats[coreid].tx +=1;
391             stats[coreid].sec_tx +=1;
392         }
393     }
394     else  //non ipsec send pkt directly, asking for IP and UDP checksum ofload
395     {
396         PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
397         int err;
398         nwalTxPktInfo_t meta_tx2={0};
399         meta2.sa_handle=nwal_HANDLE_INVALID;
400         meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
401         meta_tx2.startOffset = 0;
402         meta_tx2.ipOffBytes = netTest_MAC_HEADER_LEN;
403         meta_tx2.l4OffBytes = netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN;
404         meta_tx2.l4HdrLen = netTest_UDP_HEADER_LEN;
405         meta_tx2.ploadLen = (unsigned) ((p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+4]<<8)|
406                                         p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+4+1]) -8 ;
407         meta_tx2.pseudoHdrChecksum =
408         netTest_utilGetIPv4PsudoChkSum(&p_pkt[netTest_MAC_HEADER_LEN],8+ meta_tx2.ploadLen);
410         /* post it to netcp tx channel*/
411         meta2.u.tx_meta=&meta_tx2;
412         netapi_pktioSend(netcp_tx_chan_no_crypto,tip,&meta2,&err);
413         stats[coreid].tx +=1;
414     }
418 /**********************************************************************
419  * FUNCTION PURPOSE:  Sideband Accelerator Callback PKT RECEIVE HANDLER
420  **********************************************************************
421  * DESCRIPTION:   Sideband Accelerator Callback PKT RECEIVE HANDLER
422  *                Handles Decrypt and Encrypt operation callbacks
423  **********************************************************************/
424 void recv_sb_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
425                          PKTIO_METADATA_T meta[], int n_pkts,
426                          uint64_t ts )
428     int i;
429     int len;
430     int p;
431     netTestHead_T * p_res;
432     Ti_Pkt * tip;
433     unsigned int templen;
434     int err;
435     char * p_pkt;
436     netTestHead_T * p_head;
437     netTestHead_T temp_head;
438     int tag_cmp=0;
439     unsigned int hash[4];
440     uint8_t *p_spi;
441     netTestSA_t *p_sa_info;
443 #ifdef netTest_MULTI_THREAD
444     int coreid=Osal_nwalGetProcId();  //who we are(thread local)
445 #else
446     int coreid=0;
447 #endif
448     //nwal_AppId time;
449     unsigned long time = 0;
450     unsigned long delta_time = 0;
451     /* loop over received pkts */
452     for(i=0;i<n_pkts;i++)
453    {
454         tip = p_recv[i];
455         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
456         len = Pktlib_getPacketLen(tip);//real length
458         /*p_sa_info is for rx context */
459         p_sa_info = (netTestSA_t*)meta[i].u.rx_sb_meta->appCtxId;
460         if (p_sa_info == NULL)
461         {
462             printf("recv_sb_cb(): trie_lookup failed\n");
463             continue;
464         }
466         //is this a decrypt (rx_tunnel) complete
467         if ((int)meta[i].u.rx_sb_meta->appId == p_sa_info->rx_tunnel)
468         {
469             //time = hplib_mUtilGetPmuCCNT();
470             //delta_time = time -(unsigned long) meta[i].u.rx_sb_meta->appCtxId;
471             stats[coreid].total_decrypt_time += delta_time;
472             stats[coreid].sb_rx+=1;
473             //copy hash out of meta data (for some reason it needs endian conversion)
474             hash[0]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
475             hash[1]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
476             hash[2]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[2]);
477             hash[3]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[3]);
478             if(stats[coreid].sb_rx<=16)
479             {
480                 char *tp = (char *) &hash[0];
481                 //netTest_utilDumpHeader((long*)p_pkt, stats[coreid].sb_rx, (int)meta[i].u.rx_sb_meta->appId,0);
482             }
483             tag_cmp = memcmp(&p_pkt[len-p_sa_info->auth_tag_size],(char*) &hash[0],p_sa_info->auth_tag_size); //todo, really use meta->authTagLen
484             stats[coreid].n_auth_ok += !(tag_cmp);
485             flip_and_send_pkt(tip, p_pkt, len,1, 0);  //flip packet to echo back and send
486         }
487         //this is an encrypt (tx tunnel) complete
488         else if((int)meta[i].u.rx_sb_meta->appId== p_sa_info->tx_tunnel )
489         {
490             hash[0]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
491             hash[1]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
492             hash[2]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[2]);
493             hash[3]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[3]);
494             stats[coreid].sb_tx+=1;
495             if(stats[coreid].sb_tx<=16)
496             {
497                 //netTest_utilDumpHeader((long*)p_pkt, stats[coreid].sb_tx, (int)meta[i].u.rx_sb_meta->appId,0);
498             }
499             //put the computed tag in the packet
500              memcpy(&p_pkt[len-p_sa_info->auth_tag_size],(char*)&hash[0],p_sa_info->auth_tag_size); //todo, really use meta->authTagLen
501             {
502                 PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
503                 nwalTxPktInfo_t meta_tx={0};
504                 // now send directly 
505                 meta2.sa_handle=nwal_HANDLE_INVALID;
506                 meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID);//only outer IP header checksum. no udp checksum possible since pkt is already encrypted
507                 meta_tx.startOffset = 0;
508                 meta_tx.ipOffBytes = netTest_MAC_HEADER_LEN;
509                 meta_tx.l4OffBytes = 0;
510                 meta_tx.l4HdrLen = 0;
511                 meta_tx.ploadLen = 0;
512                 time = hplib_mUtilGetPmuCCNT();
513                 delta_time = time -(unsigned long) meta[i].u.rx_sb_meta->appCtxId;
514                 stats[coreid].total_encrypt_time += delta_time;
516                 /* post it to netcp tx channel*/
517                 meta2.u.tx_meta=&meta_tx;
518                 netapi_pktioSend(netcp_tx_chan_no_crypto,tip,&meta2,&err);
519                 //netapi_pktioSend(netcp_tx_chan_esp,tip,&meta2,&err);
520                 hplib_cacheWbInv(p_pkt,len);
521                 stats[coreid].tx +=1;
522             }
523         }
524         else printf("netapi recv_sb_cb: unknown appiD %x \n",meta[i].u.rx_sb_meta->appId );
525     }
528 /**********************************************************************
529  * FUNCTION PURPOSE:  Packet receive Callback
530  *
531  **********************************************************************
532  * DESCRIPTION:   packet Receive callback
533  **********************************************************************/
534 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
535                          PKTIO_METADATA_T meta[], int n_pkts,
536                          uint64_t ts )
538     int i;
539     int len;
540     int p;
541     netTestHead_T * p_res;
542     Ti_Pkt * tip;
543     unsigned int templen;
544     int err = 0;
545     char * p_pkt;
546     netTestHead_T * p_head;
547     netTestHead_T temp_head;
548     netTestSA_t *p_sa_info;
549     uint8_t *p_spi;
550     uint8_t p_iv[16];
551     uint8_t p_add[8];
552     uint8_t p_add1[1500];
553     int16_t       retVal;
554     unsigned long t1;
555     unsigned long t2;
556     unsigned long long ct1;
557     unsigned long long ct2;
558     unsigned long long n_c_ops;
559     nwalGlobCxtInfo_t   nwalGlobCxt;
560     nwalLocCxtInfo_t    nwalLocCxt;
562     Cppi_HostDesc*          pPloadDesc;
563     int ifno;
564     uint16_t enet_port = 0;
566 #ifdef netTest_MULTI_THREAD
567     int coreid=Osal_nwalGetProcId();  //who we are(thread local)
568 #else
569     int coreid=0;
570 #endif
571     p_head=&temp_head;
573     t1=hplib_mUtilGetPmuCCNT();
574     ct1 =Osal_cache_op_measure(&n_c_ops);
576     /* loop over received pkts */
577     for(i=0;i<n_pkts;i++)
578     {
579         ifno = ((unsigned int)meta[i].u.rx_meta->appId)&0xff;
580         
581         enet_port = meta[i].u.rx_meta->enetPort;
582         tip = p_recv[i];
584         Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);/*ignore templen */
585         len = Pktlib_getPacketLen(tip)-4;   /*real length, subtract mac trailer */
586         Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
587         Pktlib_setPacketLen(tip,len);
589         if(((unsigned int)meta[i].u.rx_meta->appId) == expPkt_appid)
590         {
591             netapi_Log("recv_cb: received exception packet\n");
592             Pktlib_freePacket(tip);
593             if(((unsigned int)meta[i].u.rx_meta->rxFlag1  & NWAL_RX_IP_FRAGMENT_PKT) ==
594                                              NWAL_RX_IP_FRAGMENT_PKT)
595             {
596                 stats[coreid].exceptionPktsFrag+=1;
597             }
598             else
599             {
600                 stats[coreid].exceptionPktsOther+=1;
601             }
602             continue;
603         }
604         //debug: validate descriptor */
605         if(Pktlib_getNextPacket(tip) != 0) 
606         {
607             printf(" rcv_cb, nexpkt != NULL");
608         }
610         if(coreid<TUNE_NETAPI_NUM_CORES)
611         {
612             stats[coreid].rx+=1;
613             if (ifno < TUNE_NETAPI_MAX_NUM_MAC)
614                 stats[coreid].if_rx[ifno]+=1;
615         }
617 #ifdef DEBUG_DESC
618         if(coreid<TUNE_NETAPI_NUM_CORES)
619         {
620             if (stats[coreid].rx<16)
621             {
622                 netapi_Log(">rx dmp.."); 
623                 netTest_utilDumpDescr((long *) tip, stats[coreid].rx);
624             }
625             else if (stats[coreid].rx>99) 
626             {
627                 netapi_Log(">rx dmp.."); 
628                 netTest_utilDumpDescr((long *) tip,stats[coreid].rx);
629             }
630         }
631 #endif
632 #if 0
633         //
634         if(stats[coreid].rx<=16)
635         {
636             netTest_utilDumpHeader((long*)p_pkt,stats[coreid].rx, (int)meta[i].u.rx_meta->appId,meta[i].u.rx_meta->rxFlag1);
637             netTest_utilDumpBuffer((long*)p_pkt,len);
638         }
639 #endif
640         /* check header */
641         memcpy(p_head,&p_pkt[netTest_MAC_HEADER_LEN],sizeof(netTestHead_T));
643         /* check for IPSEC ESP or AH packet, 0x32 is ESP tunnel mode, 0x33 is AH tunnel mode*/
644         if (((p_head->ip[2]&0x0000ff00)==0x00003200) || ((p_head->ip[2]&0x0000ff00)==0x00003300))
645         {
646             if (!netTest_utilCheckHeader(p_head,&meta[i]))
647             {
648                 printf("recv_cb: error in ipsec pkt\n");
649                 stats[coreid].n_bad+=1;Pktlib_freePacket(tip); 
650                 continue;
651             }
653             //process IP SEC PACKET
654             if (netTestCfg.ipsec_mode_rx == IPSEC_MODE_RX_SIDEBAND)
655             {
656                 p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]);
657                 p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa_rx, (char *)p_spi ,4);
658                 if (p_sa_info == NULL)
659                 {
660                     printf("recv_cb(): trie_lookup() failed\n");
661                     continue;
662                 }
664                 //ship to crypto for decrypt!!
665                 //12 byte auth tag
666                 PKTIO_METADATA_T meta2 = {PKTIO_META_SB_TX,{0},0};
667                 nwalDmTxPayloadInfo_t meta_tx={0};
669                 meta2.sa_handle = (void*) p_sa_info->rx_tunnel;
671                 memcpy(&meta_tx, &(p_sa_info->tx_payload_info), sizeof(nwalDmTxPayloadInfo_t));
673                 meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -p_sa_info->auth_tag_size;
674                 meta_tx.authSize = len - meta_tx.authOffset - p_sa_info->auth_tag_size;
676                 if (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CTR)
677                 {
678                     memcpy(&p_iv[0], &p_sa_info->key_params->pEncKey[16], 4);
679                     memcpy(&p_iv[4], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
680                     p_iv[12] = 0;
681                     p_iv[13] = 0;
682                     p_iv[14] = 0;
683                     p_iv[15] = 1;
684                     meta_tx.pEncIV = &p_iv[0];
685                  
686                 }
687                 else if ((p_sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
688                             (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CCM))
689                 {
690                         memcpy(&p_iv[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
691                         meta_tx.pEncIV = &p_iv[0];
692                         /* aad is the ESP header which is 8 bytes */
693                         memcpy(&p_add[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN], 8);
694                         meta_tx.pAad= &p_add[0];
695                         meta_tx.aadSize = 8;
696                 }
697                 else if (p_sa_info->authMode == NWAL_SA_AALG_GMAC)
698                 {
699                     memcpy(&p_iv[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
700                         meta_tx.pAuthIV= &p_iv[0];
701                         /* aad is the ESP header which is 8 bytes */
702                         memcpy(&p_add[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN], 8);
703                         meta_tx.pAad= &p_add[0];
704                         meta_tx.aadSize = 8;
705                 }
706                 else if (p_sa_info->cipherMode ==  NWAL_SA_EALG_NULL)
707                 {
708                     meta_tx.pEncIV = NULL;
709                 }
710                 else
711                 {
712                     meta_tx.pEncIV = &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN ];
713                 }
714                
715                 meta_tx.appCtxId = (nwal_AppId)p_sa_info;
717                 /* post it to netcp sb tx channel*/
718                 meta2.u.tx_sb_meta=&meta_tx;
720                 netapi_pktioSend(netcp_sb_tx_chan,tip,&meta2,&err);
721                 continue;
722             }
723             else
724             {
725                 //inflow mode.  flip and send
726                 flip_and_send_pkt(tip,p_pkt,len,1, enet_port);
727             }
728         }
729         /* check for udp protocol */
730         else if ((p_head->ip[2]&0x0000ff00)!=0x00001100)
731          //else if ((p_head->ip[2]&0x00ff0000)!=0x00110000)
732         {
733             stats[coreid].n_new+=1;Pktlib_freePacket(tip); continue;
734         }
735         else  //non ipsec
736         {
737             if (!netTest_utilCheckHeader(p_head,&meta[i]))
738             {
739                 stats[coreid].n_bad+=1;Pktlib_freePacket(tip);
740                 continue;
741             }
742             //just flip and send
743             flip_and_send_pkt(tip,p_pkt,len,0, enet_port);
744         }
745     }
746     t2=hplib_mUtilGetPmuCCNT();
747     ct2 =Osal_cache_op_measure(&n_c_ops);
748     stats[coreid].app_cycles +=  (unsigned long long) (t2-t1);
749     stats[coreid].tx_cache_cycles += (unsigned long long) (ct2-ct1);
752 /* Templates to build command labels at startup up time, required by open_pktio_tx_channels() */
753 nwalTxPktInfo_t txPktInfoESP = 
755     NULL,                                                                                               /* p_pkt */
756     NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID,      /* txFlags */
757     0,                                                                                                  /* lpbackPass */
758     0,                                                                                                  /* enetport */
759     0,                                                                                                  /* msuSize */
760     0,                                                                                                   /* startOffset */
761     netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN,                                                    /* saOffBytes */
762     0,                                                                                                  /* saPayLoadLen */
763     0               ,                                                                                    /* saAhIcvOffBytes */
764     0,                                                                                                 /* saAhMacSize */
765     0,                                                                                                  /* etherLenOffBytes */
766     0,                                                                                                  /* ipOffBytes */
767     0,                                                                                                  /* l4OffBytes */
768     netTest_UDP_HEADER_LEN,                                                                             /* l4HdrLen */
769     0,                                                                                                  /* pseudoHdrChecksum */
770     0                                                                                                   /* pLoadLen */
771 };
774 nwalTxPktInfo_t txPktInfoAH = 
776     NULL,                                                                                               /* p_pkt */
777     NWAL_TX_FLAG1_DO_IPSEC_AH_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM | NWAL_TX_FLAG1_META_DATA_VALID,      /* txFlags */
778     0,                                                                                                  /* lpbackPass */
779     0,                                                                                                  /* enetport */
780     0,                                                                                                  /* msuSize */
781     0,                                                                                                   /* startOffset */
782     netTest_MAC_HEADER_LEN  + netTest_IP_HEADER_LEN,                                                    /* saOffBytes */
783     0,                                                                                                  /* saPayLoadLen */
784     netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN + netTest_IPSEC_AH_FIXED_HDR_SIZE,                    /* saAhIcvOffBytes */
785     12,                                                                                                 /* saAhMacSize */
786     0,                                                                                                  /* etherLenOffBytes */
787     0,                                             /* ipOffBytes */
788     0,                                                                                                  /* l4OffBytes */
789     netTest_UDP_HEADER_LEN,                                                                            /* l4HdrLen */
790     0,                                                                                                  /* pseudoHdrChecksum */
791     0                                                                                                   /* pLoadLen */
792 };
794 nwalTxPktInfo_t txPktInfoNoCrypto = 
796     NULL,                                                                                               /* p_pkt */
797     NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID,      /* txFlags */
798     0,                                                                                                  /* lpbackPass */
799     0,                                                                                                  /* enetport */
800     0,                                                                                                  /* msuSize */
801     0,                                                                                                   /* startOffset */
802     0,                                                    /* saOffBytes */
803     0,                                                                                                  /* saPayLoadLen */
804     0               ,                                                                                    /* saAhIcvOffBytes */
805     0,                                                                                                 /* saAhMacSize */
806     0,                                                                                                  /* etherLenOffBytes */
807     0,                                                                                                  /* ipOffBytes */
808     netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN,                                        /* l4OffBytes */
809     netTest_UDP_HEADER_LEN,                                                             /* l4HdrLen */
810     0,                                                                         /* pseudoHdrChecksum */
811     0                                                                                                   /* pLoadLen */
812 };
815 void close_pktio_channels(void)
817     int err;
818     netapi_pktioClose(netcp_tx_chan_esp ,&err);
819     netapi_pktioClose(netcp_tx_chan_ah ,&err);
820     netapi_pktioClose(netcp_sb_tx_chan ,&err);
821     netapi_pktioClose(netcp_tx_chan_no_crypto,&err);
824 void open_pktio_tx_channels(void)
826     int err;
827     /* open netcp default  TX for ESP packets */
828     netcp_tx_chan_esp= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
829     if (!netcp_tx_chan_esp)
830     {
831         printf("pktio open TX failed err=%d\n",err);
832         exit(1);
833     }
834     else
835     {
836         if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
837         {
838             PKTIO_CONTROL_T control;
839             control.op = PKTIO_UPDATE_FAST_PATH;
840             PKTIO_CFG_T cfg;
841             cfg.fast_path_cfg.fp_send_option = PKTIO_FP_ESP_L4CKSUM_PORT;
842             cfg.fast_path_cfg.txPktInfo= &txPktInfoESP;
843             netapi_pktioControl(netcp_tx_chan_esp, NULL, &cfg, &control, &err);
844         }
845     }
847     /*/* open netcp default  TX for AH packets */
848     netcp_tx_chan_ah= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
849     if (!netcp_tx_chan_ah)
850     {
851         printf("pktio open TX failed err=%d\n",err);
852         exit(1);
853     }
854     else
855     {
856         if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
857         {
858             PKTIO_CONTROL_T control;
859             control.op = PKTIO_UPDATE_FAST_PATH;
860             PKTIO_CFG_T cfg;
861             cfg.fast_path_cfg.fp_send_option = PKTIO_FP_AH_L4CKSUM_PORT;
862             cfg.fast_path_cfg.txPktInfo= &txPktInfoAH;
863             netapi_pktioControl(netcp_tx_chan_ah, NULL, &cfg, &control, &err);
864         }
865     }
867     /* open netcp default  TX channels for non-Crypto packets */
868     netcp_tx_chan_no_crypto= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg,  &err);
869     if (!netcp_tx_chan_no_crypto)
870     {
871         printf("pktio open TX failed err=%d\n",err);
872         exit(1);
873     }
874     else
875     {
876         if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
877         {
878             PKTIO_CONTROL_T control;
879             control.op = PKTIO_UPDATE_FAST_PATH;
880             PKTIO_CFG_T cfg;
881             cfg.fast_path_cfg.fp_send_option = PKTIO_FP_L4CKSUM_PORT;
882             cfg.fast_path_cfg.txPktInfo= &txPktInfoNoCrypto;
883             netapi_pktioControl(netcp_tx_chan_no_crypto, NULL, &cfg, &control, &err);
884         }
885     }
887     /* open netcp default  TX channels for SB crypto */
888     netcp_sb_tx_chan= netapi_pktioOpen(netapi_handle, NETCP_SB_TX, NULL, &netcp_sb_tx_cfg,  &err);
889     if (!netcp_sb_tx_chan)
890     {
891         printf("pktio open SB TX failed err=%d\n",err);
892         exit(1);
893     }
896 #ifdef netTest_DSP_FASTPATH
897 void setup_netTestDSPFastPath(NETAPI_T handle)
900     int i;
901     int err = 0;
902     PKTIO_CFG_T dsp_pktio_cfg;
903     NETCP_CFG_CLASSIFIER_T dsp_classi;
904     NETCP_CFG_ROUTE_T dsp_route;
905     char dsp_name[PKTIO_MAX_NAME];
907     memset(&dsp_pktio_cfg, 0, sizeof (PKTIO_CFG_T));
908     memset(&dsp_classi, 0, sizeof (NETCP_CFG_CLASSIFIER_T));
909     memset(&dsp_route, 0, sizeof (NETCP_CFG_ROUTE_T));
910     for (i = 0; i < CPU_NUM_REM_FAST_PATH_CORES; i++)
911     {
912         snprintf(&dsp_name[0],PKTIO_MAX_NAME-1, "%s%d","dsp_chan", i);
913         dsp_pktio_cfg.flags1 = PKTIO_RX;
914         dsp_pktio_cfg.flags2 = PKTIO_PKT;
915         dsp_pktio_cfg.qnum = TEST_NWAL_BASE_REM_FP_RX_PKT_QUEUE + i;
916         dsp_pktio_cfg.max_n = 8;
918         /* pktio channels created here will NOT be POLLED by net_test arm application */
919         dsp_pktio_channels[i] = netapi_pktioCreate(handle,
920                                                &dsp_name[0],
921                                                (PKTIO_CB)recv_cb,
922                                                &dsp_pktio_cfg,
923                                                &err);
925         dsp_classi.classType =NETCP_CFG_CLASS_TYPE_L4;
926         dsp_classi.u.c_l4.iface = netTestCfg.dsp_mac;
927         
928         dsp_classi.u.c_l4.ip = ip_rule[netTestCfg.dsp_ip];
929         dsp_classi.u.c_l4.proto = NWAL_APP_PLOAD_PROTO_UDP;
930         dsp_classi.u.c_l4.appProto.udpPort = TEST_NWAL_BASE_REM_FP_UDP_PORT + i;
932         dsp_route.p_dest_q = dsp_pktio_channels[i];
933        
934         dsp_route.p_flow = (NETCP_CFG_FLOW_T*)NETCP_DEFAULT_FLOW;
935         
936         dsp_classifers[i] = netapi_netcpCfgAddClass(handle, 
937                                 &dsp_classi, 
938                                 (NETCP_CFG_ROUTE_HANDLE_T) &dsp_route, 
939                                 NETCP_CFG_ACTION_TO_SW,
940                                 NULL,
941                                 &err);
943         if (err != NETAPI_ERR_OK)
944         {
945             netapi_Log("setup_netTestDSPFastPath: netapi_netcpCfgAddClass failed for core %d\n", i);
946         }
947     }
948     printf("DSP Path fath setup complete\n");
951 void teardown_netTestDSPFastPath()
953     int i;
954     int err=0;
956     for (i = 0; i < CPU_NUM_REM_FAST_PATH_CORES; i++)
957     {
958         netapi_netcpCfgDelClass(netapi_handle,
959                                 dsp_classifers[i],
960                                 &err);
961         if (err != NETAPI_ERR_OK)
962         {
963             printf("teardown_netTestDSPFastPath: netapi_netcpCfgDelClass failed for core %d\n", i);
964         }
966         netapi_pktioDelete(dsp_pktio_channels[i],
967                            &err);
968         if (err != NETAPI_ERR_OK)
969         {
970             printf("teardown_netTestDSPFastPath: netapi_pktioDelete failed for core %d\n", i);
971         }
972     }
973     printf("DSP Path fath teardown complete\n");
975 #endif
978 #ifdef netTest_MULTI_THREAD
979 NETAPI_T worker_nh[TUNE_NETAPI_NUM_CORES];
981 void slow_path_thread(uint32_t index)
983     int err, i;;
984     uint32_t thread_num;
985     PKTIO_HANDLE_T *rx_chan;
986     PKTIO_HANDLE_T *sb_rx_chan;
989     cpu_set_t cpu_set;
991     thread_num = netTestCfg.sp_thread_num[index];
992     netapi_Log("slow_path_thread, mypid: %d, core_id %d\n", gettid(), netTestCfg.sp_thread_num[index]);
994     CPU_ZERO( &cpu_set);
995 #ifdef CORTEX_A8
996     for (i = netTestCfg.sp_proc_start[index]; i <= netTestCfg.sp_proc_end[index];i++)
997     {
998         printf("slow_path_thread: setting cpu %d to cpu_set\n", i);
999         CPU_SET( 0, &cpu_set);
1000     }
1001     hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);
1002 #else
1003     for (i = netTestCfg.sp_proc_start[index]; i <= netTestCfg.sp_proc_end[index];i++)
1004     {
1005         CPU_SET( i, &cpu_set);
1006     }
1007     hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);
1008 #endif
1009     worker_nh[thread_num] = netapi_init(NETAPI_CORE_MASTER,NULL);
1011     if (worker_nh[thread_num] == NULL)
1012     {
1013         printf("slow_path_thread: netapi_init failure, exiting\n");
1014         exit(1);
1015     }
1016     netapi_setCookie(worker_nh[thread_num],(void*)(thread_num | NET_TEST_SP_THREAD_MASK));
1018     scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],&our_sched_cfg, &err);
1019     if (!scheduler[thread_num]) 
1020     {
1021         printf("sched create failed for core%d\n",thread_num);
1022         goto ERR_slow_path_thread;
1023     }
1024     scheduler[thread_num]->config.yield = NETAPI_TRUE;
1025     scheduler[thread_num]->config.pollGarbageQ = NETAPI_TRUE;
1026     scheduler[thread_num]->config.pollCtrlQ = NETAPI_TRUE;
1027     printf("Slow Path thread: %d setup complete, running on ARM CORE: %d\n", i,i);
1028     /* Entry point to scheduler */
1029     netapi_schedRun(scheduler[thread_num], &err);
1031 ERR_slow_path_thread:
1032     printf("slow_path_thread: calling netapi_shutdown\n");
1033     netapi_shutdown(worker_nh[thread_num]);
1036 void fast_path_thread(uint32_t index)
1038     int err, i;
1039     PKTIO_HANDLE_T *rx_chan;
1040     PKTIO_HANDLE_T *sb_rx_chan;
1041     uint32_t thread_num;
1044     cpu_set_t cpu_set;
1046     CPU_ZERO( &cpu_set);
1047     thread_num = netTestCfg.fp_thread_num[index];
1048 #ifdef CORTEX_A8
1049     for (i = netTestCfg.fp_proc_start[index]; i <= netTestCfg.fp_proc_end[index];i++)
1050     {
1051         CPU_SET( 0, &cpu_set);
1052     }
1053     hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);
1054 #else
1055     for (i = netTestCfg.fp_proc_start[index]; i <= netTestCfg.fp_proc_end[index];i++)
1056     {
1057         CPU_SET( i, &cpu_set);
1058     }
1059     hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);
1060 #endif
1061     hplib_mSpinLockLock(&net_test_thread_lock);
1062     worker_nh[thread_num]=netapi_init(NETAPI_CORE_MASTER,NULL);
1063     
1064     if (worker_nh[thread_num] == NULL)
1065     {
1066         printf("fast_path_thread: netapi_init failure, exiting\n");
1067         hplib_mSpinLockUnlock(&net_test_thread_lock);
1068         exit(1);
1069     }
1070     hplib_mSpinLockUnlock(&net_test_thread_lock);
1071     /* open netcp default RX channels*/
1072     rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg,  &err);
1074     netcp_rx_cfg.flags2 = PKTIO_PKT;
1076     if(masterType == NETAPI_SYS_MASTER)
1077         netapi_pktioOpen(worker_nh[thread_num], "sysMaster", (PKTIO_CB) recv_cb, &netcp_rx_cfg,  &err);
1079     else if(masterType == NETAPI_PROC_MASTER)
1080         netapi_pktioOpen(worker_nh[thread_num], "procMaster", (PKTIO_CB) recv_cb, &netcp_rx_cfg,  &err);
1082     /* create a pktio channel for specially classified pkts */
1083     /* open netcp default tx, rx queues for sideband crypto */
1084     sb_rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_SB_RX, (PKTIO_CB) recv_sb_cb, &netcp_sb_rx_cfg,  &err);
1086     netapi_setCookie(worker_nh[thread_num],(void*)thread_num);
1087     
1088     scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],
1089                                             &our_sched_cfg,
1090                                             &err);
1091     if (!scheduler[thread_num]) 
1092         {
1093         printf("sched create failed for core%d\n",thread_num);
1094         goto ERR_fast_path_thread;
1095     }
1097  
1098     scheduler[thread_num]->config.yield = NETAPI_FALSE;
1099     scheduler[thread_num]->config.pollGarbageQ = NETAPI_FALSE;
1100     scheduler[thread_num]->config.pollCtrlQ = NETAPI_FALSE;
1101    /* Entry point to scheduler */
1102     printf("Fast Path thread: %d setup complete, running on ARM CORE: %d\n", i,i);
1103     netapi_schedRun(scheduler[thread_num], &err);
1105 ERR_fast_path_thread:
1106     netapi_pktioClose(rx_chan, &err);
1107     netapi_pktioClose(sb_rx_chan, &err);
1108     
1109     printf("fast_path_thread: calling netapi_shutdown\n");
1110     netapi_shutdown(worker_nh[thread_num]);
1113 #endif
1114 /***************************************
1115  ********** test driver*****************
1116  ***************************************/
1117 int main(int argc, char **argv)
1119     int err,i;
1120     Pktlib_HeapCfg      heapCfg;
1121     int32_t             errCode;
1122     Pktlib_HeapIfTable*  pPktifTable;
1123     FILE * fpr = NULL;
1124     int c;
1125     int configFilePresent = 0;
1127     static char usage[] = "usage: %s -f < config File Name> -t <masterType: procMaster or sysMater> >\n";
1128 #ifdef netTest_MULTI_THREAD
1129     cpu_set_t cpu_set;
1130 #endif
1131      /* install signal handler for ^c */
1132     signal(SIGINT,netTest_utilMySig);
1135     while ((c = getopt (argc, argv, "f:t:?")) != -1)
1136     {
1137        switch (c)
1138        {
1139             case 'f':
1140                 fpr = fopen(optarg, "r");
1141                 if(fpr)
1142                     configFilePresent =1;
1143                 break;
1144             case 't':
1145                 if(strcmp("sysMaster", optarg) == 0)
1146                 {
1147                     masterType = NETAPI_SYS_MASTER;
1148                 }
1149                 else if (strcmp("procMaster", optarg) == 0)
1150                 {
1151                     masterType = NETAPI_PROC_MASTER;
1152                 }
1153                 else
1154                 {
1155                     printf("%s\n", usage);
1156                 }
1157                 break;
1159             case '?':
1160                 printf("optionValue %s: %d\n", optarg, masterType);
1161                 exit(EXIT_FAILURE);
1162                 break;
1163             default:
1164                 break;
1165         }
1166     }
1168     if (!configFilePresent)
1169     {
1170         fpr = fopen(input_file_name, "r");
1171         if (fpr == NULL)
1172         {
1173             printf("main: Missing config file\n");
1174             exit(EXIT_FAILURE);
1175         }
1176     }
1178     if (initRm())
1179     {
1180         printf("main: initRm() returned error\n");
1181         exit(1);
1182     }
1183     hplib_mSpinLockInit(&net_test_thread_lock );
1184     our_netapi_default_cfg.rmHandle = rmClientServiceHandle;
1185     memset(&config_file, 0, sizeof(netTestConfigFile_t));
1186     memset(&netTestCfg, 0, sizeof(netTestConfig_t));
1188     netTest_utilProcessConfigFile(fpr,&config_file);
1190     netTest_utilParseMac(&config_file);
1192     /* parse slow path/fast path thread configuration parameters */
1193     netTest_utilParseThreadParams(&config_file);
1195     netTest_utilParseIP(&config_file);
1197     netTest_utilParseIpsecMode(&config_file);
1199     /* DSP mac processing */
1200     parse_dsp_mac(&config_file.dsp_mac[0]);
1202     /* DSP IP processing */
1203     parse_dsp_ip(&config_file.dsp_ip[0]);
1205     /* IPSEC interface number processing */
1206     parse_simple_param_u32((char*)&config_file.ipsec_if_no[0], &netTestCfg.ipsec_if_no);
1208     netTest_utilParseSA(&config_file);
1210     parse_simple_param_u32(&config_file.dest_udp_port_config, &netTestCfg.dest_udp_port_config);
1212     memset(&sa_info, 0, sizeof(sa_info));
1215 #ifdef netTest_MULTI_THREAD
1216     /* assign main net_test thread to run on core 0 */
1217     CPU_ZERO( &cpu_set);
1218     CPU_SET( 0, &cpu_set);
1219     hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
1220 #endif
1222     /* create netapi */
1224     netapi_handle = netapi_init(masterType,
1225                                 &our_netapi_default_cfg);
1227     if (netapi_handle == NULL)
1228     {
1229         printf("main: netapi_init failure, exiting\n");
1230         closeRm();
1231         exit(1);
1232     }
1234     /* configure expection packet handling with netapi */
1235     expPkt_appid = netapi_netcpCfgExceptions(netapi_handle, 
1236                                              7,
1237                                              NETCP_CFG_ACTION_TO_SW,
1238                                              (NETCP_CFG_ROUTE_HANDLE_T) NULL);
1240     /* open the main heap */
1241     ourHeap = Pktlib_findHeapByName("netapi");
1242     if (!ourHeap)
1243     {
1244         printf("Pktlib_findHeapByName()  fail\n");
1245         closeRm();
1246         exit(1);
1247     }
1249     open_pktio_tx_channels();
1251     /* create scheduler instance */
1252     our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
1253     if (!our_sched)
1254     {
1255         printf("sched create failed\n");
1256         closeRm();
1257         exit(1);
1258     }
1261     /*create net_test MAC interfaces, attach IP to created MAC interfaces */
1262     netTest_utilCreateInterfaces(netTestCfg.num_macs, netTestCfg.num_ips);
1264     /* lookup Database for SA context, this is used by packet processing routines to get RX and TX SA information*/
1265     p_trie_sa_rx = trie_new();
1266     p_trie_sa_tx = trie_new();
1267     if (!p_trie_sa_rx || !p_trie_sa_tx)
1268     {
1269         printf("trie alloc for SA  failed\n");
1270         closeRm();
1271         exit(1);
1272     }
1274 #ifdef netTest_DSP_FASTPATH
1275     if (masterType == NETAPI_SYS_MASTER)
1276     {
1277         setup_netTestDSPFastPath(netapi_handle);
1278     }
1279 #endif
1281     netTest_utilCreateDefaultFlow(netapi_handle, masterType);
1282     /* Create RX SA's, RX Policy and TX SA's, all SA configuration parameters are read from net_test_config.txt file */
1283     netTest_utilCreateSecAssoc();
1285 #ifdef netTest_MULTI_THREAD
1287     /* create and set affinity of slow path and fast path threads to
1288     * specific CPU cores as specified in the net_test_config.txt file */
1289     netTest_utilCreateSpFpThreads(netTestCfg.num_sp_threads, 
1290                                   (NET_TEST_FUNC_PTR) slow_path_thread,
1291                                   netTestCfg.num_fp_threads,
1292                                   (NET_TEST_FUNC_PTR) fast_path_thread);
1294     printf("\n net_test_loopback running ....\n");
1295     printf("\n Enter 's' for stats or 'q'to quit net_test_loopback app, or 'h' for help\n");
1300     int c;
1301     //this thread of execution (main) now just waits on user input
1302     for(;;)
1303     {
1304        printf(">");
1305        c=getchar();
1306        if (c=='q')
1307        {
1308             QUIT=1;
1309             printf("net_test_loopback: please wait for application shutdown and resource cleanup\n");
1310             break;
1311        }
1312        else if (c=='s') netTest_utilsStatsCb(netapi_handle, &netcp_stats);
1313        else if (c=='h') printf("'q' to quit,  's' for stats, 'h' for help\n");
1314     }
1316         netTest_utilRemoveSpFpThreads(netTestCfg.num_sp_threads, netTestCfg.num_fp_threads);
1318 #else
1319     /*********************************************/
1320     /**************Entry point into scheduler ****/
1321     /*********************************************/
1322     //netTest_utilCreateSecAssoc(netcp_sb_rx_chan, netcp_sb_tx_chan,netcp_tx_chan);
1323     netapi_schedRun(our_sched, &err);
1324 #endif
1326     /* done */
1327     netTest_utilsStatsCb(netapi_handle, NULL);
1330     /* cleanup*/
1331      netTest_utilDeleteSecAssoc();
1333     netTest_utilDeleteInterfaces(netTestCfg.num_macs, netTestCfg.num_ips);
1335     /* close pktio channels we opened via open_pktio_tx_channels() */
1336     close_pktio_channels();
1337 #ifdef netTest_DSP_FASTPATH
1338     if (masterType == NETAPI_SYS_MASTER)
1339     {
1340         teardown_netTestDSPFastPath();
1341     }
1342 #endif
1344     netapi_shutdown(netapi_handle);
1345     closeRm();
1346     printf("net_test shutdown complete\n");
1350 #if 1
1351 /* Stub functions */
1352 Trie * route_init(void)
1354     return NULL;
1356 void route_add(Trie * Pt, unsigned long * Pdest_ipBE, void * Pour_route)
1359 #endif