/****************************************************************************** * File: net_test.c * Purpose: test app for netapi ****************************************************************************** * FILE: net_test.c * * DESCRIPTION: netapi user space transport * library test application * * REVISION HISTORY: * * Copyright (c) Texas Instruments Incorporated 2013 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ #include "netapi.h" #include "net_test_sa_utils.h" #include "net_test_utils.h" #include "net_test_thread_utils.h" #include "ti/drv/nwal/test/fw_rm.h" #include #include #if defined(DEVICE_K2H) #include #include #elif defined (DEVICE_K2K) #include #include #elif defined (DEVICE_K2L) #include #include #elif defined (DEVICE_K2E) #include #include #else /*Default */ #include #include #endif /* Device */ extern int QUIT; extern netTestStats_T stats[TUNE_NETAPI_NUM_CORES]; extern paSysStats_t netcp_stats; extern Rm_ServiceHandle *rmClientServiceHandle; hplib_spinLock_T net_test_thread_lock; netTestConfig_t netTestCfg; static netTestConfigFile_t config_file; char input_file_name[] = "/etc/transportnetlib/test/net_test_config.txt"; nwal_RetValue nwalRetVal; Pktlib_HeapHandle ourHeap; PKTIO_HANDLE_T *netcp_rx_chan; PKTIO_HANDLE_T *netcp_tx_chan_no_crypto; PKTIO_HANDLE_T *netcp_tx_chan_esp; PKTIO_HANDLE_T *netcp_tx_chan_ah; PKTIO_HANDLE_T *netcp_sb_tx_chan; PKTIO_HANDLE_T *netcp_sb_rx_chan; PKTIO_CFG_T netcp_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8}; PKTIO_CFG_T netcp_rx_cfg2={PKTIO_RX, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8}; PKTIO_CFG_T netcp_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8}; PKTIO_CFG_T netcp_sb_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8}; PKTIO_CFG_T netcp_sb_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8}; NETCP_CFG_IP_T ip_rule[NET_TEST_MAX_IP]; NETCP_CFG_MACIF_T mac[NET_TEST_MAX_MAC]; #ifdef netTest_DSP_FASTPATH PKTIO_HANDLE_T *dsp_pktio_channels[CPU_NUM_REM_FAST_PATH_CORES]; NETCP_CFG_CLASS_T dsp_classifers[CPU_NUM_REM_FAST_PATH_CORES]; NETCP_CFG_FLOW_HANDLE_T dsp_flow_handles[CPU_NUM_REM_FAST_PATH_CORES]; #endif NETCP_CFG_EXCEPTION_PKT_T expPkt_appid; Trie *p_trie_sa_rx; Trie *p_trie_sa_tx; /******************************************* *************NETAPI OBJECTS*************** *****************************************/ static NETAPI_CFG_T our_netapi_default_cfg= { TUNE_NETAPI_PERM_MEM_SZ, 128, //start of packet offset for hw to place data on rx for default flow TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system TUNE_NETAPI_NUM_GLOBAL_DESC, //total we will use TUNE_NETAPI_DEFAULT_NUM_BUFFERS, //#descriptors+buffers in default heap 64, //#descriptors w/o buffers in default heap TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128, //size of buffers in default heap 128, //tail room 256, //extra room 0, NULL }; NETAPI_T netapi_handle; NETAPI_SCHED_HANDLE_T * our_sched; #ifdef netTest_MULTI_THREAD NETAPI_SCHED_HANDLE_T * scheduler[TUNE_NETAPI_NUM_CORES]; #endif NETAPI_SCHED_CONFIG_T our_sched_cfg={ NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000 //every 5000000 poll loops }; netTestSA_t sa_info[MAX_SEC_INDEX]; NETCP_CFG_IPSEC_POLICY_T rx_policy[MAX_SEC_INDEX]; int masterType = NETAPI_SYS_MASTER; /******************************************************************** * FUNCTION PURPOSE: Utility function to flip and packet and send * it back to its source. ******************************************************************** * DESCRIPTION: Utility function to flip and packet and send * it back to its source. ********************************************************************/ void flip_and_send_pkt(Ti_Pkt *tip, unsigned char * p_pkt, int len, int flag, uint16_t enet_port) { unsigned char mac_temp[6]; unsigned char ip_temp[4]; unsigned char new_dest_port[2]={0x75,0x30}; // 30000 uint16_t dest_udp_port_config = 0; uint16_t blah; uint16_t i=1; /* for testing only */ uint8_t *p_spi; netTestSA_t * p_sa_info; netTestSA_t *p_sa_info_tx; uint8_t p_iv[16]; uint8_t p_add[8]; Cppi_HostDesc* pPloadDesc; uint8_t ah_len; uint32_t tunnel_id; nwalLocCxtInfo_t nwalLocCxt; netTestHead_T * p_head; netTestHead_T temp_head; int pkt_type; #ifdef netTest_MULTI_THREAD int coreid=Osal_nwalGetProcId(); //who we are(thread local) //int coreid = our_core; #else int coreid=0; #endif // netTest_utilDumpBuffer((long*)p_pkt,len); Pktlib_setPacketLen(tip,len); //flip the mac address memcpy(&mac_temp,&p_pkt[0],6); memcpy(&p_pkt[0],&p_pkt[6],6); memcpy(&p_pkt[6],&mac_temp,6); //memcpy(&p_pkt[0],real_mac_header,6); //for testing to wireshark pc //flip the ip (outer in case of ipsec) memcpy(&ip_temp, &p_pkt[netTest_MAC_HEADER_LEN+12],4); memcpy(&p_pkt[netTest_MAC_HEADER_LEN+12],&p_pkt[netTest_MAC_HEADER_LEN+12+4],4); memcpy(&p_pkt[netTest_MAC_HEADER_LEN+12+4],&ip_temp,4); p_head=&temp_head; //inner ip &udp for ipsec if (flag) { memcpy(p_head,&p_pkt[netTest_MAC_HEADER_LEN],sizeof(netTestHead_T)); if ((p_head->ip[2]&0x0000ff00)==0x00003300) { p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN + 4]); pkt_type = netTest_IPSEC_AH_PKT; } else if ((p_head->ip[2]&0x0000ff00)==0x00003200) { p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]); pkt_type = netTest_IPSEC_ESP_PKT; } else { netapi_Log("flip_and_send_pkt: un-supported IPSEC protocol\n"); Pktlib_freePacket(tip); return; } p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa_rx, (char *)p_spi ,4); if (p_sa_info == NULL) { netapi_Log("flip_and_send_pkt(): trie_lookup() failed\n"); Pktlib_freePacket(tip); return; } tunnel_id = p_sa_info->tunnel_id; p_sa_info_tx = (netTestSA_t *) trie_lookup(p_trie_sa_tx, (char *)&tunnel_id ,4); if (p_sa_info_tx == NULL) { netapi_Log("flip_and_send_pkt(): trie_lookup() failed\n"); Pktlib_freePacket(tip); return; } //just drop non-udp packet if (p_pkt[p_sa_info->tx_payload_info.encOffset+9]!=0x11) { stats[coreid].n_new+=1;Pktlib_freePacket(tip); return; } /* flip inner IP */ memcpy(&ip_temp, &p_pkt[p_sa_info->tx_payload_info.encOffset+12],4); memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+12],&p_pkt[p_sa_info->tx_payload_info.encOffset+12+4],4); memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+12+4],&ip_temp,4); /* setting udp ports */ if (netTestCfg.dest_udp_port_config == 0) { memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+netTest_IP_HEADER_LEN+2], &p_pkt[p_sa_info->tx_payload_info.encOffset+netTest_IP_HEADER_LEN],2); } else { dest_udp_port_config = htons(netTestCfg.dest_udp_port_config); memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+netTest_IP_HEADER_LEN+2], &dest_udp_port_config,2); } memset(&p_pkt[p_sa_info->tx_payload_info.encOffset+netTest_IP_HEADER_LEN+6],0,2); //checksum if (netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND) { /* inner ip checksum : leave alone, outer ip, set to 0 (we will compute on way out */ memset(&p_pkt[netTest_MAC_HEADER_LEN+10],0,2); } } else { /* flip udp port */ if (netTestCfg.dest_udp_port_config == 0) { memcpy(&p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+2], &p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN],2); } else { dest_udp_port_config = htons(netTestCfg.dest_udp_port_config); //memcpy(&p_pkt[netTest_MAC_HEADER_LEN+20+2],&new_dest_port[0],2); memcpy(&p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+2],&dest_udp_port_config,2); } memset(&p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+6],0,2);//0 udp checksum (we will compute on way out) } /*IPSEC case */ if (flag) { if (netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND) //send to crypto for encryption //12 byte auth tag { PKTIO_METADATA_T meta = {PKTIO_META_SB_TX,{0},0}; int err; nwalDmTxPayloadInfo_t meta_tx={0}; meta.sa_handle = (void*)p_sa_info_tx->tx_tunnel; //use TX SA APPID memcpy(&meta_tx, &(p_sa_info->tx_payload_info), sizeof(nwalDmTxPayloadInfo_t)); meta_tx.appCtxId = (nwal_AppId)p_sa_info_tx; meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -p_sa_info->auth_tag_size; meta_tx.authSize = len - meta_tx.authOffset - p_sa_info->auth_tag_size; meta_tx.pAuthIV=NULL; meta_tx.aadSize=0; meta_tx.pAad=NULL; if (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CTR) { memcpy(&p_iv[0], &p_sa_info->key_params->pEncKey[16], 4); memcpy(&p_iv[4], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8); p_iv[12] = 0; p_iv[13] = 0; p_iv[14] = 0; p_iv[15] = 1; meta_tx.pEncIV = &p_iv[0]; } else if ((p_sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) || (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CCM)) { memcpy(&p_iv[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8); meta_tx.pEncIV = &p_iv[0]; memcpy(&p_add[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN], 8); meta_tx.pAad= &p_add[0]; meta_tx.aadSize = 8; } else if (p_sa_info->authMode == NWAL_SA_AALG_GMAC) { memcpy(&p_iv[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8); meta_tx.pAuthIV= &p_iv[0]; memcpy(&p_add[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN], 8); meta_tx.pAad= &p_add[0]; meta_tx.aadSize = 8; } else if (p_sa_info->cipherMode == NWAL_SA_EALG_NULL) { meta_tx.pEncIV = NULL; } else { meta_tx.pEncIV = &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN ]; } /* post it to netcp sb tx channel*/ meta.u.tx_sb_meta=&meta_tx; netapi_pktioSend(netcp_sb_tx_chan,tip,&meta,&err); } else { //INFLOW TX, send pkt directly, asking for IP and UDP checksum offloads AND IPSEC to be applied PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0}; int err; nwalTxPktInfo_t meta_tx={0}; meta.sa_handle = (void*)p_sa_info_tx->tx_tunnel; //use TX SA APPID meta_tx.startOffset = p_sa_info_tx->tx_pkt_info.startOffset; meta_tx.ipOffBytes =p_sa_info_tx->tx_payload_info.encOffset; meta_tx.l4OffBytes = p_sa_info_tx->tx_pkt_info.l4OffBytes; meta_tx.l4HdrLen = p_sa_info_tx->tx_pkt_info.l4HdrLen; meta_tx.ploadLen = (unsigned) ((p_pkt[meta_tx.l4OffBytes+4]<<8)|p_pkt[meta_tx.l4OffBytes+4+1]) -8 ; meta_tx.saOffBytes= p_sa_info_tx->tx_pkt_info.saOffBytes; if (pkt_type == netTest_IPSEC_AH_PKT) { memset(&p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+netTest_IPSEC_AH_FIXED_HDR_SIZE],0,netTest_IPSEC_AH_FIXED_HDR_SIZE); meta_tx.txFlag1 = p_sa_info_tx->tx_pkt_info.txFlag1; meta_tx.saPayloadLen=len-netTest_MAC_HEADER_LEN; //don't inlcude mac meta_tx.saAhMacSize = 12; meta_tx.saAhIcvOffBytes = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN + netTest_IPSEC_AH_FIXED_HDR_SIZE; meta_tx.enetPort = enet_port; memcpy(&p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+4],&p_sa_info_tx->spi,4); } else if (pkt_type == netTest_IPSEC_ESP_PKT) { meta_tx.txFlag1 = p_sa_info_tx->tx_pkt_info.txFlag1; meta_tx.saPayloadLen=len-netTest_MAC_HEADER_LEN-netTest_IP_HEADER_LEN; //don't include mac and ip outer header meta_tx.enetPort = 0; memcpy(&p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN],&p_sa_info_tx->spi,4); } else { printf("flip_and_send_pkt: invalid ESP protocol\n"); return; } meta_tx.pseudoHdrChecksum = netTest_utilGetIPv4PsudoChkSum(&p_pkt[meta_tx.ipOffBytes],8+ meta_tx.ploadLen); /* post it to netcp tx channel*/ meta.u.tx_meta=&meta_tx; #ifdef DEBUG_DESC if (stats[coreid].sec_tx<20) netTest_utilDumpDescr((long *) tip, stats[coreid].sec_tx); #endif if ( pkt_type == netTest_IPSEC_ESP_PKT) netapi_pktioSend(netcp_tx_chan_esp,tip,&meta,&err); else if ( pkt_type == netTest_IPSEC_AH_PKT) netapi_pktioSend(netcp_tx_chan_ah,tip,&meta,&err); stats[coreid].tx +=1; stats[coreid].sec_tx +=1; } } else //non ipsec send pkt directly, asking for IP and UDP checksum ofload { PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0}; int err; nwalTxPktInfo_t meta_tx2={0}; meta2.sa_handle=nwal_HANDLE_INVALID; meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ); meta_tx2.startOffset = 0; meta_tx2.ipOffBytes = netTest_MAC_HEADER_LEN; meta_tx2.l4OffBytes = netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN; meta_tx2.l4HdrLen = netTest_UDP_HEADER_LEN; meta_tx2.ploadLen = (unsigned) ((p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+4]<<8)| p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN+4+1]) -8 ; meta_tx2.pseudoHdrChecksum = netTest_utilGetIPv4PsudoChkSum(&p_pkt[netTest_MAC_HEADER_LEN],8+ meta_tx2.ploadLen); /* post it to netcp tx channel*/ meta2.u.tx_meta=&meta_tx2; netapi_pktioSend(netcp_tx_chan_no_crypto,tip,&meta2,&err); stats[coreid].tx +=1; } } /********************************************************************** * FUNCTION PURPOSE: Sideband Accelerator Callback PKT RECEIVE HANDLER ********************************************************************** * DESCRIPTION: Sideband Accelerator Callback PKT RECEIVE HANDLER * Handles Decrypt and Encrypt operation callbacks **********************************************************************/ void recv_sb_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[], PKTIO_METADATA_T meta[], int n_pkts, uint64_t ts ) { int i; int len; int p; netTestHead_T * p_res; Ti_Pkt * tip; unsigned int templen; int err; char * p_pkt; netTestHead_T * p_head; netTestHead_T temp_head; int tag_cmp=0; unsigned int hash[4]; uint8_t *p_spi; netTestSA_t *p_sa_info; #ifdef netTest_MULTI_THREAD int coreid=Osal_nwalGetProcId(); //who we are(thread local) #else int coreid=0; #endif //nwal_AppId time; unsigned long time = 0; unsigned long delta_time = 0; /* loop over received pkts */ for(i=0;iappCtxId; if (p_sa_info == NULL) { printf("recv_sb_cb(): trie_lookup failed\n"); continue; } //is this a decrypt (rx_tunnel) complete if ((int)meta[i].u.rx_sb_meta->appId == p_sa_info->rx_tunnel) { //time = hplib_mUtilGetPmuCCNT(); //delta_time = time -(unsigned long) meta[i].u.rx_sb_meta->appCtxId; stats[coreid].total_decrypt_time += delta_time; stats[coreid].sb_rx+=1; //copy hash out of meta data (for some reason it needs endian conversion) hash[0]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[0]); hash[1]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[1]); hash[2]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[2]); hash[3]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[3]); if(stats[coreid].sb_rx<=16) { char *tp = (char *) &hash[0]; //netTest_utilDumpHeader((long*)p_pkt, stats[coreid].sb_rx, (int)meta[i].u.rx_sb_meta->appId,0); } 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 stats[coreid].n_auth_ok += !(tag_cmp); flip_and_send_pkt(tip, p_pkt, len,1, 0); //flip packet to echo back and send } //this is an encrypt (tx tunnel) complete else if((int)meta[i].u.rx_sb_meta->appId== p_sa_info->tx_tunnel ) { hash[0]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[0]); hash[1]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[1]); hash[2]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[2]); hash[3]= netTest_utilHtonl( meta[i].u.rx_sb_meta->pAuthTag[3]); stats[coreid].sb_tx+=1; if(stats[coreid].sb_tx<=16) { //netTest_utilDumpHeader((long*)p_pkt, stats[coreid].sb_tx, (int)meta[i].u.rx_sb_meta->appId,0); } //put the computed tag in the packet memcpy(&p_pkt[len-p_sa_info->auth_tag_size],(char*)&hash[0],p_sa_info->auth_tag_size); //todo, really use meta->authTagLen { PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0}; nwalTxPktInfo_t meta_tx={0}; // now send directly meta2.sa_handle=nwal_HANDLE_INVALID; 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 meta_tx.startOffset = 0; meta_tx.ipOffBytes = netTest_MAC_HEADER_LEN; meta_tx.l4OffBytes = 0; meta_tx.l4HdrLen = 0; meta_tx.ploadLen = 0; time = hplib_mUtilGetPmuCCNT(); delta_time = time -(unsigned long) meta[i].u.rx_sb_meta->appCtxId; stats[coreid].total_encrypt_time += delta_time; /* post it to netcp tx channel*/ meta2.u.tx_meta=&meta_tx; netapi_pktioSend(netcp_tx_chan_no_crypto,tip,&meta2,&err); //netapi_pktioSend(netcp_tx_chan_esp,tip,&meta2,&err); hplib_cacheWbInv(p_pkt,len); stats[coreid].tx +=1; } } else printf("netapi recv_sb_cb: unknown appiD %x \n",meta[i].u.rx_sb_meta->appId ); } } /********************************************************************** * FUNCTION PURPOSE: Packet receive Callback * ********************************************************************** * DESCRIPTION: packet Receive callback **********************************************************************/ void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[], PKTIO_METADATA_T meta[], int n_pkts, uint64_t ts ) { int i; int len; int p; netTestHead_T * p_res; Ti_Pkt * tip; unsigned int templen; int err = 0; char * p_pkt; netTestHead_T * p_head; netTestHead_T temp_head; netTestSA_t *p_sa_info; uint8_t *p_spi; uint8_t p_iv[16]; uint8_t p_add[8]; uint8_t p_add1[1500]; int16_t retVal; unsigned long t1; unsigned long t2; unsigned long long ct1; unsigned long long ct2; unsigned long long n_c_ops; nwalGlobCxtInfo_t nwalGlobCxt; nwalLocCxtInfo_t nwalLocCxt; Cppi_HostDesc* pPloadDesc; int ifno; uint16_t enet_port = 0; #ifdef netTest_MULTI_THREAD int coreid=Osal_nwalGetProcId(); //who we are(thread local) #else int coreid=0; #endif p_head=&temp_head; t1=hplib_mUtilGetPmuCCNT(); ct1 =Osal_cache_op_measure(&n_c_ops); /* loop over received pkts */ for(i=0;iappId)&0xff; enet_port = meta[i].u.rx_meta->enetPort; tip = p_recv[i]; Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);/*ignore templen */ len = Pktlib_getPacketLen(tip)-4; /*real length, subtract mac trailer */ Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len); Pktlib_setPacketLen(tip,len); if(((unsigned int)meta[i].u.rx_meta->appId) == expPkt_appid) { netapi_Log("recv_cb: received exception packet\n"); Pktlib_freePacket(tip); if(((unsigned int)meta[i].u.rx_meta->rxFlag1 & NWAL_RX_IP_FRAGMENT_PKT) == NWAL_RX_IP_FRAGMENT_PKT) { stats[coreid].exceptionPktsFrag+=1; } else { stats[coreid].exceptionPktsOther+=1; } continue; } //debug: validate descriptor */ if(Pktlib_getNextPacket(tip) != 0) { printf(" rcv_cb, nexpkt != NULL"); } if(coreidrx dmp.."); netTest_utilDumpDescr((long *) tip, stats[coreid].rx); } else if (stats[coreid].rx>99) { netapi_Log(">rx dmp.."); netTest_utilDumpDescr((long *) tip,stats[coreid].rx); } } #endif #if 0 // if(stats[coreid].rx<=16) { netTest_utilDumpHeader((long*)p_pkt,stats[coreid].rx, (int)meta[i].u.rx_meta->appId,meta[i].u.rx_meta->rxFlag1); netTest_utilDumpBuffer((long*)p_pkt,len); } #endif /* check header */ memcpy(p_head,&p_pkt[netTest_MAC_HEADER_LEN],sizeof(netTestHead_T)); /* check for IPSEC ESP or AH packet, 0x32 is ESP tunnel mode, 0x33 is AH tunnel mode*/ if (((p_head->ip[2]&0x0000ff00)==0x00003200) || ((p_head->ip[2]&0x0000ff00)==0x00003300)) { if (!netTest_utilCheckHeader(p_head,&meta[i])) { printf("recv_cb: error in ipsec pkt\n"); stats[coreid].n_bad+=1;Pktlib_freePacket(tip); continue; } //process IP SEC PACKET if (netTestCfg.ipsec_mode_rx == IPSEC_MODE_RX_SIDEBAND) { p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]); p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa_rx, (char *)p_spi ,4); if (p_sa_info == NULL) { printf("recv_cb(): trie_lookup() failed\n"); continue; } //ship to crypto for decrypt!! //12 byte auth tag PKTIO_METADATA_T meta2 = {PKTIO_META_SB_TX,{0},0}; nwalDmTxPayloadInfo_t meta_tx={0}; meta2.sa_handle = (void*) p_sa_info->rx_tunnel; memcpy(&meta_tx, &(p_sa_info->tx_payload_info), sizeof(nwalDmTxPayloadInfo_t)); meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -p_sa_info->auth_tag_size; meta_tx.authSize = len - meta_tx.authOffset - p_sa_info->auth_tag_size; if (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CTR) { memcpy(&p_iv[0], &p_sa_info->key_params->pEncKey[16], 4); memcpy(&p_iv[4], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8); p_iv[12] = 0; p_iv[13] = 0; p_iv[14] = 0; p_iv[15] = 1; meta_tx.pEncIV = &p_iv[0]; } else if ((p_sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) || (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CCM)) { memcpy(&p_iv[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8); meta_tx.pEncIV = &p_iv[0]; /* aad is the ESP header which is 8 bytes */ memcpy(&p_add[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN], 8); meta_tx.pAad= &p_add[0]; meta_tx.aadSize = 8; } else if (p_sa_info->authMode == NWAL_SA_AALG_GMAC) { memcpy(&p_iv[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8); meta_tx.pAuthIV= &p_iv[0]; /* aad is the ESP header which is 8 bytes */ memcpy(&p_add[0], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN], 8); meta_tx.pAad= &p_add[0]; meta_tx.aadSize = 8; } else if (p_sa_info->cipherMode == NWAL_SA_EALG_NULL) { meta_tx.pEncIV = NULL; } else { meta_tx.pEncIV = &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN ]; } meta_tx.appCtxId = (nwal_AppId)p_sa_info; /* post it to netcp sb tx channel*/ meta2.u.tx_sb_meta=&meta_tx; netapi_pktioSend(netcp_sb_tx_chan,tip,&meta2,&err); continue; } else { //inflow mode. flip and send flip_and_send_pkt(tip,p_pkt,len,1, enet_port); } } /* check for udp protocol */ else if ((p_head->ip[2]&0x0000ff00)!=0x00001100) //else if ((p_head->ip[2]&0x00ff0000)!=0x00110000) { stats[coreid].n_new+=1;Pktlib_freePacket(tip); continue; } else //non ipsec { if (!netTest_utilCheckHeader(p_head,&meta[i])) { stats[coreid].n_bad+=1;Pktlib_freePacket(tip); continue; } //just flip and send flip_and_send_pkt(tip,p_pkt,len,0, enet_port); } } t2=hplib_mUtilGetPmuCCNT(); ct2 =Osal_cache_op_measure(&n_c_ops); stats[coreid].app_cycles += (unsigned long long) (t2-t1); stats[coreid].tx_cache_cycles += (unsigned long long) (ct2-ct1); } /* Templates to build command labels at startup up time, required by open_pktio_tx_channels() */ nwalTxPktInfo_t txPktInfoESP = { NULL, /* p_pkt */ NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID, /* txFlags */ 0, /* lpbackPass */ 0, /* enetport */ 0, /* msuSize */ 0, /* startOffset */ netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN, /* saOffBytes */ 0, /* saPayLoadLen */ 0 , /* saAhIcvOffBytes */ 0, /* saAhMacSize */ 0, /* etherLenOffBytes */ 0, /* ipOffBytes */ 0, /* l4OffBytes */ netTest_UDP_HEADER_LEN, /* l4HdrLen */ 0, /* pseudoHdrChecksum */ 0 /* pLoadLen */ }; nwalTxPktInfo_t txPktInfoAH = { NULL, /* p_pkt */ NWAL_TX_FLAG1_DO_IPSEC_AH_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM | NWAL_TX_FLAG1_META_DATA_VALID, /* txFlags */ 0, /* lpbackPass */ 0, /* enetport */ 0, /* msuSize */ 0, /* startOffset */ netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN, /* saOffBytes */ 0, /* saPayLoadLen */ netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN + netTest_IPSEC_AH_FIXED_HDR_SIZE, /* saAhIcvOffBytes */ 12, /* saAhMacSize */ 0, /* etherLenOffBytes */ 0, /* ipOffBytes */ 0, /* l4OffBytes */ netTest_UDP_HEADER_LEN, /* l4HdrLen */ 0, /* pseudoHdrChecksum */ 0 /* pLoadLen */ }; nwalTxPktInfo_t txPktInfoNoCrypto = { NULL, /* p_pkt */ NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID, /* txFlags */ 0, /* lpbackPass */ 0, /* enetport */ 0, /* msuSize */ 0, /* startOffset */ 0, /* saOffBytes */ 0, /* saPayLoadLen */ 0 , /* saAhIcvOffBytes */ 0, /* saAhMacSize */ 0, /* etherLenOffBytes */ 0, /* ipOffBytes */ netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN, /* l4OffBytes */ netTest_UDP_HEADER_LEN, /* l4HdrLen */ 0, /* pseudoHdrChecksum */ 0 /* pLoadLen */ }; void close_pktio_channels(void) { int err; netapi_pktioClose(netcp_tx_chan_esp ,&err); netapi_pktioClose(netcp_tx_chan_ah ,&err); netapi_pktioClose(netcp_sb_tx_chan ,&err); netapi_pktioClose(netcp_tx_chan_no_crypto,&err); } void open_pktio_tx_channels(void) { int err; /* open netcp default TX for ESP packets */ netcp_tx_chan_esp= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err); if (!netcp_tx_chan_esp) { printf("pktio open TX failed err=%d\n",err); exit(1); } else { if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW) { PKTIO_CONTROL_T control; control.op = PKTIO_UPDATE_FAST_PATH; PKTIO_CFG_T cfg; cfg.fast_path_cfg.fp_send_option = PKTIO_FP_ESP_L4CKSUM_PORT; cfg.fast_path_cfg.txPktInfo= &txPktInfoESP; netapi_pktioControl(netcp_tx_chan_esp, NULL, &cfg, &control, &err); } } /*/* open netcp default TX for AH packets */ netcp_tx_chan_ah= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err); if (!netcp_tx_chan_ah) { printf("pktio open TX failed err=%d\n",err); exit(1); } else { if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW) { PKTIO_CONTROL_T control; control.op = PKTIO_UPDATE_FAST_PATH; PKTIO_CFG_T cfg; cfg.fast_path_cfg.fp_send_option = PKTIO_FP_AH_L4CKSUM_PORT; cfg.fast_path_cfg.txPktInfo= &txPktInfoAH; netapi_pktioControl(netcp_tx_chan_ah, NULL, &cfg, &control, &err); } } /* open netcp default TX channels for non-Crypto packets */ netcp_tx_chan_no_crypto= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err); if (!netcp_tx_chan_no_crypto) { printf("pktio open TX failed err=%d\n",err); exit(1); } else { if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW) { PKTIO_CONTROL_T control; control.op = PKTIO_UPDATE_FAST_PATH; PKTIO_CFG_T cfg; cfg.fast_path_cfg.fp_send_option = PKTIO_FP_L4CKSUM_PORT; cfg.fast_path_cfg.txPktInfo= &txPktInfoNoCrypto; netapi_pktioControl(netcp_tx_chan_no_crypto, NULL, &cfg, &control, &err); } } /* open netcp default TX channels for SB crypto */ netcp_sb_tx_chan= netapi_pktioOpen(netapi_handle, NETCP_SB_TX, NULL, &netcp_sb_tx_cfg, &err); if (!netcp_sb_tx_chan) { printf("pktio open SB TX failed err=%d\n",err); exit(1); } } #ifdef netTest_DSP_FASTPATH void setup_netTestDSPFastPath(NETAPI_T handle) { int i; int err = 0; PKTIO_CFG_T dsp_pktio_cfg; NETCP_CFG_CLASSIFIER_T dsp_classi; NETCP_CFG_ROUTE_T dsp_route; memset(&dsp_pktio_cfg, 0, sizeof (PKTIO_CFG_T)); memset(&dsp_classi, 0, sizeof (NETCP_CFG_CLASSIFIER_T)); memset(&dsp_route, 0, sizeof (NETCP_CFG_ROUTE_T)); char dsp_name[PKTIO_MAX_NAME]; for (i = 0; i < CPU_NUM_REM_FAST_PATH_CORES; i++) { snprintf(&dsp_name[0],32, "%s%d","dsp_chan", i); dsp_pktio_cfg.flags1 = PKTIO_RX; dsp_pktio_cfg.flags2 = PKTIO_PKT; dsp_pktio_cfg.qnum = TEST_NWAL_BASE_REM_FP_RX_PKT_QUEUE + i; dsp_pktio_cfg.max_n = 8; /* pktio channels created here will NOT be POLLED by net_test arm application */ dsp_pktio_channels[i] = netapi_pktioCreate(handle, &dsp_name[0], (PKTIO_CB)recv_cb, &dsp_pktio_cfg, &err); if (!dsp_pktio_channels[i]) { netapi_Log("setup_netTestDSPFastPath: failed for core %d\n", i); } dsp_classi.classType =NETCP_CFG_CLASS_TYPE_L4; dsp_classi.u.c_l4.iface = netTestCfg.dsp_mac; dsp_classi.u.c_l4.ip = ip_rule[netTestCfg.dsp_ip]; dsp_classi.u.c_l4.proto = NWAL_APP_PLOAD_PROTO_UDP; dsp_classi.u.c_l4.appProto.udpPort = TEST_NWAL_BASE_REM_FP_UDP_PORT + i; dsp_route.p_dest_q = dsp_pktio_channels[i]; dsp_route.p_flow = (NETCP_CFG_FLOW_T*)NETCP_DEFAULT_FLOW; dsp_classifers[i] = netapi_netcpCfgAddClass(handle, &dsp_classi, (NETCP_CFG_ROUTE_HANDLE_T) &dsp_route, NETCP_CFG_ACTION_TO_SW, NULL, &err); if (err != NETAPI_ERR_OK) { netapi_Log("setup_netTestDSPFastPath: netapi_netcpCfgAddClass failed for core %d\n", i); } } printf("DSP Path fath setup complete\n"); } void teardown_netTestDSPFastPath() { int i; int err=0; for (i = 0; i < CPU_NUM_REM_FAST_PATH_CORES; i++) { netapi_netcpCfgDelClass(netapi_handle, dsp_classifers[i], &err); if (err != NETAPI_ERR_OK) { printf("teardown_netTestDSPFastPath: netapi_netcpCfgDelClass failed for core %d\n", i); } netapi_pktioDelete(dsp_pktio_channels[i], &err); if (err != NETAPI_ERR_OK) { printf("teardown_netTestDSPFastPath: netapi_pktioDelete failed for core %d\n", i); } } printf("DSP Path fath teardown complete\n"); } #endif #ifdef netTest_MULTI_THREAD NETAPI_T worker_nh[TUNE_NETAPI_NUM_CORES]; void slow_path_thread(uint32_t index) { int err, i;; uint32_t thread_num; PKTIO_HANDLE_T *rx_chan; PKTIO_HANDLE_T *sb_rx_chan; cpu_set_t cpu_set; thread_num = netTestCfg.sp_thread_num[index]; netapi_Log("slow_path_thread, mypid: %d, core_id %d\n", gettid(), netTestCfg.sp_thread_num[index]); CPU_ZERO( &cpu_set); #ifdef CORTEX_A8 for (i = netTestCfg.sp_proc_start[index]; i <= netTestCfg.sp_proc_end[index];i++) { printf("slow_path_thread: setting cpu %d to cpu_set\n", i); CPU_SET( 0, &cpu_set); } hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL); #else for (i = netTestCfg.sp_proc_start[index]; i <= netTestCfg.sp_proc_end[index];i++) { CPU_SET( i, &cpu_set); } hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL); #endif worker_nh[thread_num] = netapi_init(NETAPI_CORE_MASTER,NULL); if (worker_nh[thread_num] == NULL) { printf("slow_path_thread: netapi_init failure, exiting\n"); exit(1); } netapi_setCookie(worker_nh[thread_num],(void*)(thread_num | NET_TEST_SP_THREAD_MASK)); scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],&our_sched_cfg, &err); if (!scheduler[thread_num]) { printf("sched create failed for core%d\n",thread_num); goto ERR_slow_path_thread; } scheduler[thread_num]->config.yield = NETAPI_TRUE; scheduler[thread_num]->config.pollGarbageQ = NETAPI_TRUE; scheduler[thread_num]->config.pollCtrlQ = NETAPI_TRUE; printf("Slow Path thread: %d setup complete, running on ARM CORE: %d\n", i,i); /* Entry point to scheduler */ netapi_schedRun(scheduler[thread_num], &err); ERR_slow_path_thread: printf("slow_path_thread: calling netapi_shutdown\n"); netapi_shutdown(worker_nh[thread_num]); } void fast_path_thread(uint32_t index) { int err, i; PKTIO_HANDLE_T *rx_chan; PKTIO_HANDLE_T *sb_rx_chan; uint32_t thread_num; cpu_set_t cpu_set; CPU_ZERO( &cpu_set); thread_num = netTestCfg.fp_thread_num[index]; #ifdef CORTEX_A8 for (i = netTestCfg.fp_proc_start[index]; i <= netTestCfg.fp_proc_end[index];i++) { CPU_SET( 0, &cpu_set); } hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL); #else for (i = netTestCfg.fp_proc_start[index]; i <= netTestCfg.fp_proc_end[index];i++) { netapi_Log("fast_path_thread: start core %d end core %d\n", netTestCfg.fp_proc_start[index], netTestCfg.fp_proc_end[index]); netapi_Log("fast_path_thread: setting cpu %d to cpu_set\n", i); CPU_SET( i, &cpu_set); } hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL); #endif hplib_mSpinLockLock(&net_test_thread_lock); worker_nh[thread_num]=netapi_init(NETAPI_CORE_MASTER,NULL); if (worker_nh[thread_num] == NULL) { printf("fast_path_thread: netapi_init failure, exiting\n"); hplib_mSpinLockUnlock(&net_test_thread_lock); exit(1); } hplib_mSpinLockUnlock(&net_test_thread_lock); /* open netcp default RX channels*/ rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg, &err); netcp_rx_cfg.flags2 = PKTIO_PKT; if(masterType == NETAPI_SYS_MASTER) netapi_pktioOpen(worker_nh[thread_num], "sysMaster", (PKTIO_CB) recv_cb, &netcp_rx_cfg, &err); else if(masterType == NETAPI_PROC_MASTER) netapi_pktioOpen(worker_nh[thread_num], "procMaster", (PKTIO_CB) recv_cb, &netcp_rx_cfg, &err); /* create a pktio channel for specially classified pkts */ /* open netcp default tx, rx queues for sideband crypto */ sb_rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_SB_RX, (PKTIO_CB) recv_sb_cb, &netcp_sb_rx_cfg, &err); netapi_setCookie(worker_nh[thread_num],(void*)thread_num); scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num], &our_sched_cfg, &err); if (!scheduler[thread_num]) { printf("sched create failed for core%d\n",thread_num); goto ERR_fast_path_thread; //exit(1); } scheduler[thread_num]->config.yield = NETAPI_FALSE; scheduler[thread_num]->config.pollGarbageQ = NETAPI_FALSE; scheduler[thread_num]->config.pollCtrlQ = NETAPI_FALSE; //sleep(100000); /* Entry point to scheduler */ printf("Fast Path thread: %d setup complete, running on ARM CORE: %d\n", i,i); netapi_schedRun(scheduler[thread_num], &err); ERR_fast_path_thread: netapi_pktioClose(rx_chan, &err); netapi_pktioClose(sb_rx_chan, &err); printf("fast_path_thread: calling netapi_shutdown\n"); netapi_shutdown(worker_nh[thread_num]); } #endif /*************************************** ********** test driver***************** ***************************************/ int main(int argc, char **argv) { int err,i; Pktlib_HeapCfg heapCfg; int32_t errCode; Pktlib_HeapIfTable* pPktifTable; FILE * fpr = NULL; int c; static char usage[] = "usage: %s -f < config File Name> -t >\n"; #ifdef netTest_MULTI_THREAD cpu_set_t cpu_set; #endif /* install signal handler for ^c */ signal(SIGINT,netTest_utilMySig); while ((c = getopt (argc, argv, "f:t:?")) != -1) { switch (c) { case 'f': fpr = fopen(optarg, "r"); printf("main: filename1 %s\n", optarg); break; case 't': if(strcmp("sysMaster", optarg) == 0) { masterType = NETAPI_SYS_MASTER; } else if (strcmp("procMaster", optarg) == 0) { masterType = NETAPI_PROC_MASTER; } else { printf("%s\n", usage); } printf("optionValue %s: %d\n", optarg, masterType); break; case '?': printf("optionValue %s: %d\n", optarg, masterType); exit(EXIT_FAILURE); break; default: break; } } if (fpr ==NULL) fpr = fopen(input_file_name, "r"); if (initRm()) { printf("main: initRm() returned error\n"); exit(1); } hplib_mSpinLockInit(&net_test_thread_lock ); our_netapi_default_cfg.rmHandle = rmClientServiceHandle; memset(&config_file, 0, sizeof(netTestConfigFile_t)); memset(&netTestCfg, 0, sizeof(netTestConfig_t)); netTest_utilProcessConfigFile(fpr,&config_file); netTest_utilParseMac(&config_file); /* parse slow path/fast path thread configuration parameters */ netTest_utilParseThreadParams(&config_file); netTest_utilParseIP(&config_file); netTest_utilParseIpsecMode(&config_file); /* DSP mac processing */ parse_dsp_mac(&config_file.dsp_mac[0]); /* DSP IP processing */ parse_dsp_ip(&config_file.dsp_ip[0]); /* IPSEC interface number processing */ parse_simple_param_u32((char*)&config_file.ipsec_if_no[0], &netTestCfg.ipsec_if_no); netTest_utilParseSA(&config_file); parse_simple_param_u32(&config_file.dest_udp_port_config, &netTestCfg.dest_udp_port_config); memset(&sa_info, 0, sizeof(sa_info)); #ifdef netTest_MULTI_THREAD /* assign main net_test thread to run on core 0 */ CPU_ZERO( &cpu_set); CPU_SET( 0, &cpu_set); hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL); #endif /* create netapi */ netapi_handle = netapi_init(masterType, &our_netapi_default_cfg); if (netapi_handle == NULL) { printf("main: netapi_init failure, exiting\n"); closeRm(); exit(1); } /* configure expection packet handling with netapi */ netapi_netcpCfgExceptions(netapi_handle, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_DISCARD, (NETCP_CFG_ROUTE_HANDLE_T) NULL); expPkt_appid = netapi_netcpCfgExceptions(netapi_handle, 7, NETCP_CFG_ACTION_TO_SW, (NETCP_CFG_ROUTE_HANDLE_T) NULL); /* open the main heap */ ourHeap = Pktlib_findHeapByName("netapi"); if (!ourHeap) { printf("Pktlib_findHeapByName() fail\n"); closeRm(); exit(1); } open_pktio_tx_channels(); /* create scheduler instance */ our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err); if (!our_sched) { printf("sched create failed\n"); closeRm(); exit(1); } /*create net_test MAC interfaces, attach IP to created MAC interfaces */ netTest_utilCreateInterfaces(netTestCfg.num_macs, netTestCfg.num_ips); /* lookup Database for SA context, this is used by packet processing routines to get RX and TX SA information*/ p_trie_sa_rx = trie_new(); p_trie_sa_tx = trie_new(); if (!p_trie_sa_rx || !p_trie_sa_tx) { printf("trie alloc for SA failed\n"); closeRm(); exit(1); } #ifdef netTest_DSP_FASTPATH if (masterType == NETAPI_SYS_MASTER) { setup_netTestDSPFastPath(netapi_handle); } #endif netTest_utilCreateDefaultFlow(netapi_handle, masterType); /* Create RX SA's, RX Policy and TX SA's, all SA configuration parameters are read from net_test_config.txt file */ netTest_utilCreateSecAssoc(); #ifdef netTest_MULTI_THREAD { /* create and set affinity of slow path and fast path threads to * specific CPU cores as specified in the net_test_config.txt file */ netTest_utilCreateSpFpThreads(netTestCfg.num_sp_threads, (NET_TEST_FUNC_PTR) slow_path_thread, netTestCfg.num_fp_threads, (NET_TEST_FUNC_PTR) fast_path_thread); printf("\n net_test_loopback running ....\n"); printf("\n Enter 's' for stats or 'q'to quit net_test_loopback app, or 'h' for help\n"); int c; //this thread of execution (main) now just waits on user input for(;;) { printf(">"); c=getchar(); if (c=='q') { QUIT=1; printf("net_test_loopback: please wait for application shutdown and resource cleanup\n"); break; } else if (c=='s') netTest_utilsStatsCb(netapi_handle, &netcp_stats); else if (c=='h') printf("'q' to quit, 's' for stats, 'h' for help\n"); } netTest_utilRemoveSpFpThreads(netTestCfg.num_sp_threads, netTestCfg.num_fp_threads); } #else /*********************************************/ /**************Entry point into scheduler ****/ /*********************************************/ //netTest_utilCreateSecAssoc(netcp_sb_rx_chan, netcp_sb_tx_chan,netcp_tx_chan); netapi_schedRun(our_sched, &err); #endif /* done */ netTest_utilsStatsCb(netapi_handle, NULL); /* cleanup*/ netTest_utilDeleteSecAssoc(); netTest_utilDeleteInterfaces(netTestCfg.num_macs, netTestCfg.num_ips); /* close pktio channels we opened via open_pktio_tx_channels() */ close_pktio_channels(); #ifdef netTest_DSP_FASTPATH if (masterType == NETAPI_SYS_MASTER) { teardown_netTestDSPFastPath(); } #endif netapi_shutdown(netapi_handle); closeRm(); printf("net_test shutdown complete\n"); } #if 1 /* Stub functions */ Trie * route_init(void) { return NULL; } void route_add(Trie * Pt, unsigned long * Pdest_ipBE, void * Pour_route) { } #endif