/****************************************** * File: net_test.c * Purpose: test app for netapi ************************************************************** * FILE: net_test.c * * DESCRIPTION: netapi user space transport * library test application * * REVISION HISTORY: rev 0.0.1 * * Copyright (c) Texas Instruments Incorporated 2010-2011 * * 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 #include #include #include #include "trie.h" #include "string.h" #include "netapi.h" #include "pktio.h" #include #include "net_test.h" #include #define EXPERIMENTAL #ifdef EXPERIMENTAL #include "router.c" Trie * our_router; OUR_ROUTE_T routes[MAX_ROUTES]= { {0,{0xD4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x14,0x02,0x08,0x00},0}, {0,{0x00,0x00,0x0,0x00,0x0,0x0, 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00},0}, {0,{0xD4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x14,0x02,0x08,0x00},0}, {0,{0x00,0x15,0x60,0xa1,0xf7,0xbe, 0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00},0}, {0,{0xd4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00},0}}; unsigned int ip[MAX_ROUTES]={BE(0x0a0100c8),BE(0x0a00000a),BE(0x0a02000a),BE(0xc0a8010a),BE(0x9eda6719)}; #endif //#define TEST_TIMERS /*************debug********************/ void dump_descr(unsigned long *p, int n) { printf("--------dump of descriptor %d %x\n", n, (int) p); printf("> %x %x %x %x %x %x %x %x\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]); printf("> %x %x %x %x %x %x %x %x\n",p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]); printf("-----------------------------\n"); } void dump_header(unsigned long *p, int n, int a, int r) { printf("--------dump of header %d %x appID=%x flag1=%x\n", n, (int) p,a,r); printf("> %x %x %x %x %x %x %x %x\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]); printf("> %x %x %x %x %x %x %x %x\n",p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]); printf("> %x %x %x %x %x %x %x %x\n",p[16],p[17],p[18],p[19],p[20],p[21],p[22],p[23]); printf("> %x %x %x %x %x %x %x %x\n",p[24],p[25],p[26],p[27],p[28],p[29],p[30],p[31]); printf("-----------------------------\n"); } /*****************************************/ //************for multi pkt burst xfer test in loopback mode #define TX_BURST 700 int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK; nwalTxPSCmdInfo_t flowPSCmdInfo; //this device: 10.0.0.100, mac 0x,01,02,03,04,05 and .. 0x6 //test packet, setup for loopback (so dest is ourself) static uint8_t testPkt[] = { /* MAC header */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04, 0x08, 0x00, /* IP header */ 0x45, 0x00, 0x00, 0x6c, /* Length (including this header) */ 0x00, 0x00, 0x00, 0x00, 0x05, 0x11, 0x00, 0x00, /* Header checksum */ 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x64, /* UDP header */ 0x12, 0x34, 0x05, 0x55, 0x00, 0x58, /* Length, including this header */ 0x00, 0x00, /* Header checksum */ /* Payload */ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81 }; char input_file_name[] = "net_test_config.txt"; #define MAX_LINE_LENGTH 40 #define TEST_PAYLOAD_LEN 80 #define TEST_PKT_IP_OFFSET_BYTES 14 #define TEST_PKT_UDP_OFFSET_BYTES 34 #define TEST_PKT_PLOAD_OFFSET_BYTES 42 #define TEST_PKT_UDP_HDR_LEN 8 /* Offsets to length fields */ #define TEST_PKT_OFFSET_IP_LEN 16 #define TEST_PKT_OFFSET_UDP_LEN 38 #define TEST_PKT_LEN 122 /* The pseudo header checksum of the packet except for the 16 bit length */ #define TEST_PKT_PSEUDO_HDR_CHKSUM_SANS_LEN 0x0FFC void example_fast_poll( PKTIO_HANDLE_T * p_pktio, int max_pkts); void example_fast_pushpop(Pktlib_HeapHandle p_heap, int ntrials); void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[], PKTIO_METADATA_T meta[], int n_pkts, uint64_t ts ); //#include "arpa/inet.h" long htonl(long x) { long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 | (x&0xff)<<24 ; return temp; } /******************************************************************** * FUNCTION PURPOSE: Ones complement addition utility ******************************************************************** ********************************************************************/ uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2) { uint32_t result; result = (uint32_t)v1 + (uint32_t)v2; result = (result >> 16) + (result & 0xffff); result = (result >> 16) + (result & 0xffff); return ((uint16_t)result); } /******************************************************************** * FUNCTION PURPOSE: Ones complement checksum utility ******************************************************************** ********************************************************************/ uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords) { uint16_t chksum = 0; uint16_t v; uint32_t i; uint32_t j; for (i = j = 0; i < nwords; i++, j+=2) { v = (p[j] << 8) | p[j+1]; chksum = test_utilOnesComplementAdd (chksum, v); } return (chksum); } /* utilOnesCompChkSum */ /************************************************************************************** * FUNCTION PURPOSE: Compute ipv4 psudo checksum ************************************************************************************** * DESCRIPTION: Compute ipv4 psudo checksum **************************************************************************************/ uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen) { uint16_t psudo_chksum; psudo_chksum = test_utilOnesCompChkSum (&data[12], 4); psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]); psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen); return (psudo_chksum); } /* utilGetIpv4PsudoChkSum */ /* net test default configuration */ netTestConfig_t config = { {0x00,0x01,0x02,0x03,0x05,0x05}, {0x00,0x01,0x02,0x03,0x05,0x06}, {10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {10, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {192,168 , 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, {192,168 , 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, IPSEC_MODE_RX_SIDEBAND, IPSEC_MODE_TX_SIDEBAND, 0 }; #if 1 //goes with real tx (to laptop) unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x04,0x05, 0x08,0x00}; unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa}; #endif #if 0 //goes with loopback unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05, 0x00,0x11,0x22,0x33,0x44,0x55, 0x08,0x00}; #endif #define NE 65536 HEAD_T *nat; #define NP 5000 int n_pkt = NP; STATS_T stats; Trie * P_trie; Trie *p_trie_sa; HEAD_T pkts[NP]; #define PERSLOW 10 //% of pkts that will not be fastpath'd int perslow= PERSLOW; /******************************************* *************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 }; Pktlib_HeapHandle OurHeap; Pktlib_HeapHandle specialSmall; Pktlib_HeapHandle specialLarge; PKTIO_HANDLE_T *our_chan; PKTIO_HANDLE_T *netcp_rx_chan; PKTIO_HANDLE_T *netcp_rx_chan2; PKTIO_HANDLE_T *netcp_tx_chan; PKTIO_HANDLE_T *netcp_sb_tx_chan; PKTIO_HANDLE_T *netcp_sb_rx_chan; PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8}; PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8}; PKTIO_CFG_T netcp_rx_cfg2={PKTIO_R, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8}; PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8}; PKTIO_CFG_T netcp_sb_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8}; PKTIO_CFG_T netcp_sb_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8}; void house(NETAPI_SCHED_HANDLE_T *s); NETAPI_T netapi_handle; NETAPI_SCHED_HANDLE_T * our_sched; NETAPI_SCHED_CONFIG_T our_sched_cfg={ NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000 //every 5000000 poll loops }; void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats); NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock; NETAPI_TIMER_T t1; NETAPI_TIMER_T t2; NETAPI_TIMER_T t3; void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th, int n_fired, //# timers fired NETAPI_TIMER_LIST_T fired_list, uint64_t currentTime); NETCP_CFG_IP_T ip_rule0; NETCP_CFG_IP_T ip_rule1; NETCP_CFG_CLASS_T class_0; NETCP_CFG_CLASS_T class_1; NETCP_CFG_CLASS_T class_2; NETCP_CFG_FLOW_HANDLE_T specialFlow; NETCP_CFG_CLASSIFIER_T class_0_cfg= { NETCP_CFG_CLASS_TYPE_L4, { {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2500}} } }; NETCP_CFG_CLASSIFIER_T class_1_cfg= { NETCP_CFG_CLASS_TYPE_L4, { {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2502}} } }; NETCP_CFG_ROUTE_T class2_route= { NULL, NULL //* to be filled in }; NETCP_CFG_CLASSIFIER_T class_2_cfg= { NETCP_CFG_CLASS_TYPE_L3_L4, { {0, 4 ,0/*fill in below*/ , NULL, NULL, //L2/L3 NWAL_APP_PLOAD_PROTO_UDP, {2504}} //L4 } }; PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL}; /* security objects. (for loopback mode) */ netTestSA_t sa_info[6]; int netapi_algorithm_set = 0; int netapi_sec_sa_mode = 2; /* tmannan-end */ //NETCP_CFG_SA_T rx_tunnel; //NETCP_CFG_SA_T tx_tunnel; NETCP_CFG_IPSEC_POLICY_T rx_policy[4]; //void * rx_data_mode_handle; //void * tx_data_mode_handle; //void * rx_inflow_mode_handle; //void * tx_inflow_mode_handle; /* rx */ NETAPI_SEC_SA_INFO_T rx_sa [4] = { { NWAL_SA_DIR_INBOUND, 0x11111111, //spi nwal_IpSecProtoESP, //ESP mode nwal_SA_MODE_TUNNEL, //tunnel mode nwal_IPV4, //v4 { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (them) -> set below */ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (us)-> set below*/ 64,/* replayWindow */ NWAL_SA_AALG_HMAC_SHA1, NWAL_SA_EALG_AES_CBC, 0,0 //na }, { NWAL_SA_DIR_INBOUND, 0x22222222, //spi nwal_IpSecProtoESP, //ESP mode nwal_SA_MODE_TUNNEL, //tunnel mode nwal_IPV4, //v4 { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (them) -> set below */ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (us)-> set below*/ 64,/* replayWindow */ NWAL_SA_AALG_HMAC_SHA2_256, NWAL_SA_EALG_AES_CTR, 0,0 //na }, { NWAL_SA_DIR_INBOUND, 0x33333333, //spi nwal_IpSecProtoESP, //ESP mode nwal_SA_MODE_TUNNEL, //tunnel mode nwal_IPV4, //v4 { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (them) -> set below */ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (us)-> set below*/ 64,/* replayWindow */ NWAL_SA_AALG_HMAC_SHA2_256, NWAL_SA_EALG_3DES_CBC, 0,0 //na }, { NWAL_SA_DIR_INBOUND, 0x44444444, //spi nwal_IpSecProtoESP, //ESP mode nwal_SA_MODE_TUNNEL, //tunnel mode nwal_IPV4, //v4 { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (them) -> set below */ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (us)-> set below*/ 64,/* replayWindow */ NWAL_SA_AALG_HMAC_MD5, NWAL_SA_EALG_NULL, 0,0 //na } }; /*tx */ NETAPI_SEC_SA_INFO_T tx_sa[4]= { { NWAL_SA_DIR_OUTBOUND, 0x11111111, //spi nwal_IpSecProtoESP, //ESP mode nwal_SA_MODE_TUNNEL, //tunnel mode nwal_IPV4, //v4 { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (us) -> set below */ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (them) -> set below*/ 64, /* NA replayWindow */ NWAL_SA_AALG_HMAC_SHA1, NWAL_SA_EALG_AES_CBC, 0,0 //seq no }, { NWAL_SA_DIR_OUTBOUND, 0x22222222, //spi nwal_IpSecProtoESP, //ESP mode nwal_SA_MODE_TUNNEL, //tunnel mode nwal_IPV4, //v4 { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (us) -> set below */ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (them) -> set below*/ 64, /* NA replayWindow */ NWAL_SA_AALG_HMAC_SHA2_256, NWAL_SA_EALG_AES_CTR, 0,0 //seq no }, { NWAL_SA_DIR_OUTBOUND, 0x33333333, //spi nwal_IpSecProtoESP, //ESP mode nwal_SA_MODE_TUNNEL, //tunnel mode nwal_IPV4, //v4 { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (us) -> set below */ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (them) -> set below*/ 64, /* NA replayWindow */ NWAL_SA_AALG_HMAC_SHA2_256, NWAL_SA_EALG_3DES_CBC, 0,0 //seq no }, { NWAL_SA_DIR_OUTBOUND, 0x44444444, //spi nwal_IpSecProtoESP, //ESP mode nwal_SA_MODE_TUNNEL, //tunnel mode nwal_IPV4, //v4 { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (us) -> set below */ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (them) -> set below*/ 64, /* NA replayWindow */ NWAL_SA_AALG_HMAC_MD5, NWAL_SA_EALG_NULL, 0,0 //seq no } }; static nwalSecKeyParams_t ourTXKeyParams[4] ={ { 16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/ 20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA1 */ NULL, //set below NULL, //set below }, { 20, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_AES_CTR and 0 bytes Salt*/ 32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */ NULL, //set below NULL, //set below }, { 24, /* encKeySize: DES-CBC: 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/ 32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */ NULL, //set below NULL, //set below }, { 0, /* NULL*/ 16, /* MD5, 16 bytes */ NULL, //set below NULL, //set below } }; /* these keys are for aes-ctr and hmac sha2_256 */ static nwalSecKeyParams_t ourRXKeyParams[4] ={ { 16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/ 20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA1 */ NULL, //set below NULL, //set below }, { 20, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_AES_CTR and 0 bytes Salt*/ 32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */ NULL, //set below NULL, //set below }, { 24, /* encKeySize: DES-CBC: 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/ 32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */ NULL, //set below NULL, //set below }, { 0, /* NWAL_SA_EALG_NULL*/ 16, /* NWAL_SA_AALG_HMAC_MD5, 16 bytes */ NULL, //set below NULL, //set below } }; static uint8_t ourAuthKey[36] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23 }; ; static uint8_t ourEncrKey[36] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x30, 0x31, 0x32, 0x33 }; /*************************END NETAPI OBJECTS***********************/ #define START_SRC_IP 0x0a00000a #define DST_IP 0xc0a80001 #define NEW_START_SRC_IP 0x9eda000a #define DST_PORT 0x555 #define START_SRC_PORT 0x1234 #define NEW_START_SRC_PORT 100 void update_header(HEAD_T * p_head, int len) { unsigned char *p = (unsigned char *) &p_head->udp[1]; len -= (20+14); /* update ip checksum */ /* update udp checksum */ /* update length */ *p= (len&0xff00)>>8; *(p+1) = len&0xff; } #if 0 void gen_pkts(int np) { int i; int ip = START_SRC_IP &0xff; int port= START_SRC_PORT; //HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP}, // {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}}; HEAD_T temp; memcpy(&temp,&testPkt[0],sizeof(HEAD_T)); for(i=0;(i254) {(ip=START_SRC_IP&0xff); port+=1; } temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip); temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port); temp.udp[1] = htonl(temp.udp[1]); } n_pkt=np; } #endif void build_table(Trie * p_trie) { int i; int sport=NEW_START_SRC_PORT; HEAD_T temp,temp2; KEY_T key; memcpy(&temp,&testPkt[14],sizeof(temp)); //insert entry into trie key.src_ip = temp.ip[3]; key.dst_ip = temp.ip[4]; key.src_port= (temp.udp[0]&0xffff0000)>>16; key.dst_port= (temp.udp[0]&0x0000ffff); trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[0]); //asociate with nat entry 0 //build nat table for(i=0;i<100;i++) { memcpy(&temp2,&testPkt[14],sizeof(temp)); temp2.udp[0] = (temp2.udp[0] & 0xffff0000) | sport; memcpy(&nat[i], &temp2, sizeof(temp2)); sport+= 1; } } //===========stub transmitter================== void send_pkt(Ti_Pkt *pkt, int len) { //just free pkt. Don't send Pktlib_freePacket((Ti_Pkt*)pkt); return; } //==========stub slow path============ void slow_path(Ti_Pkt *pkt, int len) { // debug: check descriptor for validity by verifying that desciptor link field is null as expected\n"); {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}} //just free pkt Pktlib_freePacket((Ti_Pkt*)pkt); return; } /* check header */ struct LastPktInfo { int iface; int ipcsum; int l4csum; } ; static struct LastPktInfo lpInfo; int check_header(HEAD_T * p_head, PKTIO_METADATA_T * p_meta) { if (NWAL_RX_FLAG1_META_DATA_VALID & p_meta->u.rx_meta->rxFlag1) { lpInfo.iface = ((unsigned int)p_meta->u.rx_meta->appId) &0xff; //last byte is interface num lpInfo.ipcsum =(p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_MASK )== NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_ACK ? 1 : 0; lpInfo.l4csum = (p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_MASK )== ((NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_ACK) << NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_SHIFT) ? 1 : 0; if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC) { stats.sec_rx++; } if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC_POLICY) { stats.secp_rx++; } if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_CLASS) { int c= ((unsigned int)p_meta->u.rx_meta->appId >>8)&0xffff; if (c==0) stats.n_class0_rx +=1; else if (c==1) stats.n_class1_rx +=1; else if (c==2) stats.n_class2_rx +=1; else printf("**NET_TEST RX -unknown class: %x\n", p_meta->u.rx_meta->appId); } } return 1; } #define PKT_LEN 1400 void test_alloc_free(int n) { int i; Ti_Pkt * b; for(i=0;i /*--------------reassembly benchmark--------------------------------*/ void our_reassemble_bench(int nfrags) { paIPReassemblyConfig_t Config={5,128,10000 }; int i,j; int len; Ti_Pkt tip; char *buffer; unsigned long v1; unsigned long v2; unsigned long sum1=0; unsigned long sum2=0; paEx_reassemLibInit(&Config); for(j=0;j<200/nfrags;j++) { for(i=0;i>8; buffer[7]= (temp&0xff); temp = 20+40*8; buffer[2]= (temp&0xff00)>>8; buffer[3]= (temp&0xff); Pktlib_setPacketLen(tip, temp); v1= netapi_timing_stop(); paEx_reassemLibProc(tip, 0xffff); v2= netapi_timing_stop(); sum1+= v2-v1; } sum2 += v2-v1; } printf("reasssembly test: %d trials, %d frags/pkt %d cycles/frag %d cycles/last frag\n",j,nfrags, sum1/(j*nfrags), sum2/(j)); } #endif /*--------------basic pktio send/recv benchmark----------------------*/ unsigned int timings[10]; void our_pktio_bench(int ntrials) { int i; #define NBATCH 8 Ti_Pkt tip; unsigned char * pData; int len; int n; int err; int sum =0; Osal_cache_op_measure_reset(); for(i=0;i<10;i++) timings[i]=0; printf("calibration loop .. "); for(i=0;i<1000;i++) { vv1= netapi_timing_stop(); vv2= netapi_timing_stop(); sum+=(vv2-vv1); } printf(" accuracy = +- %d cycles\n", sum/1000); sleep(1); PKTIO_METADATA_T meta[10]={0}; //send single, recv single for(i=0;i=TX_BURST) return NULL; //just gen pkts to warm swtich, so that it knows //our mac is valid } b=Pktlib_allocPacket(heap2use,size); if (!b) {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;}; //debug - way to validate descriptor {Ti_Pkt* k= Pktlib_getNextPacket(b); if(k != 0) {printf(" genpkt, nexpkt != NULL");}} //get pointer to buffer area of packet Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len); if (!buffer) {printf("net_test: get_pkt() heap returned empty buffer %d \n", n); return NULL;}; #if 0 if (pktloopback==0) { temp = (long long) rand(); temp *= PKT_LEN; temp /= RAND_MAX; temp +=2; *p_len = (int) temp; *p_len = *p_len &0xfffffffe; temp = (long long) rand(); temp *= n_pkt; temp /= RAND_MAX; ind = (int) temp; update_header(&pkts[ind],*p_len); //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len); memcpy(&buffer[0], &mac_header[0],14); memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T)); } else #endif //copy test packet into buffer { memcpy(&buffer[0], buf2cpy, copy_size); *p_len = copy_size; } return b; } static int eof=0; /*-------------------------------------------------------------- *----------utility to flip a packet and send *--------------------back to source---------------------------- * flag=1 => ipsec *--------------------------------------------------------------*/ void flip_and_send_pkt(Ti_Pkt *tip, unsigned char * p_pkt, int len, int flag) { unsigned char mac_temp[6]; unsigned char ip_temp[4]; unsigned char new_dest_port[2]={0x75,0x30}; // 30000 uint16_t blah; uint16_t i=1; /* for testing only */ uint8_t *p_spi; netTestSA_t * p_sa_info; uint8_t p_iv[16]; Pktlib_setPacketLen(tip,len); //mac 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 //ip (outer in case of ipsec) memcpy(&ip_temp, &p_pkt[14+12],4); memcpy(&p_pkt[14+12],&p_pkt[14+12+4],4); memcpy(&p_pkt[14+12+4],&ip_temp,4); //outer checksum to 0 if (!flag) memset(&p_pkt[14+10],0,2); //inner ip &udp for ipsec if (flag) { p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]); p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa, (char *)p_spi ,4); if (p_sa_info == NULL) { printf("flip_and_send_pkt(): trie_lookup() failed\n"); return; } //just drop non-udp packet if (p_pkt[p_sa_info->tx_payload_info.encOffset+9]!=0x11) { stats.n_new+=1;Pktlib_freePacket(tip); return; } 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); //udp memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+20+2],&new_dest_port[0],2); memset(&p_pkt[p_sa_info->tx_payload_info.encOffset+20+6],0,2); //checksum if (config.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND) { //inner ip checksum : leave alone #if 0 blah=test_utilOnesCompChkSum (&p_pkt[14+20+8+16], 10); p_pkt[14+20+8+16+10]= (blah&0xff00)>>8; p_pkt[14+20+8+16+11]= blah&0xff; #endif //tbd udp checksum (leave at 0) //outer ip, set to 0 (we will compute on way out memset(&p_pkt[14+10],0,2); } else { //#else //inflow, don't touch outer , clear inner //DALmemset(&p_pkt[14+20+8+16+10],0,2); //inner checksum, we will compute on way out //outer ip checksum : leave alone #if 0 blah = test_utilOnesCompChkSum (&p_pkt[14], 10); p_pkt[14+10]= (blah&0xff00)>>8; p_pkt[14+11]= blah&0xff; #endif } } else { memset(&p_pkt[14+20+6],0,2);//0 udp checksum (we will compute on way out memcpy(&p_pkt[14+20+2],&new_dest_port[0],2); } //IPSEC case, if (flag) { if (config.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=p_sa_info->tx_data_mode_handle; //use TX SA context #if 0 meta_tx.ploadLen = len; meta_tx.encOffset =p_sa_info->tx_payload_info.encOffset; meta_tx.authOffset =netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN; //meta_tx.encSize=len - 14- 20-8-16-12; meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -netTest_ICV_LEN; //meta_tx.authSize= len -14-20-12; meta_tx.authSize = len - meta_tx.authOffset - netTest_ICV_LEN; //meta_tx.encIvSize=16; meta_tx.encIvSize = p_sa_info->tx_payload_info.encIvSize; //meta_tx.pEncIV= &p_pkt[14+20+8]; //just use same IV.. #endif memcpy(&meta_tx, &(p_sa_info->tx_payload_info), sizeof(nwalDmTxPayloadInfo_t)); meta_tx.ploadLen = len; meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -netTest_ICV_LEN; meta_tx.authSize = len - meta_tx.authOffset - netTest_ICV_LEN; meta_tx.encIvSize = p_sa_info->tx_payload_info.encIvSize; #if 0 printf("flip_and_send_pkt(): encOffset %d\n", meta_tx.encOffset); printf("flip_and_send_pkt():authOffset %d\n", meta_tx.authOffset); printf("flip_and_send_pkt(): encSize %d\n", meta_tx.encSize); printf("flip_and_send_pkt(): authSize %d\n", meta_tx.authSize); printf("flip_and_send_pkt(): encIvSize %d\n", meta_tx.encIvSize); #endif if (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CTR) { memcpy(&p_iv[0], &ourEncrKey[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_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.authIvSize=0; meta_tx.pAuthIV=NULL; meta_tx.aadSize=0; meta_tx.pAad=NULL; /* post it to netcp sb tx channel*/ meta_tx.appCtxId = netapi_timing_start(); meta.u.tx_sb_meta=&meta_tx; pktio_send(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}; #define USE_COPY #ifdef USE_COPY //debug: see if re-using RX descriptor for TX is causing our SA lockup { int new_len=0; Ti_Pkt new_tip = get_pkt(0, &new_len, specialLarge , len+10 , &p_pkt[0] , len); if (!new_tip) { printf("net_test> new_tip NULL\n"); } else { Pktlib_setPacketLen(new_tip,new_len); Pktlib_freePacket(tip); tip=new_tip; Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&new_len); //reset p_pkt to point to new buffer as its used below Cppi_setTimeStamp (Cppi_DescType_HOST, (Cppi_Desc *) tip,stats.sec_tx); } } if (len <1500) { eof+=1; } #endif meta.sa_handle=p_sa_info->tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied //meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_META_DATA_VALID ); meta_tx.txFlag1 = p_sa_info->tx_pkt_info.txFlag1; meta_tx.enetPort=0; //meta_tx.saOffBytes=14+20; meta_tx.saOffBytes= p_sa_info->tx_pkt_info.saOffBytes; meta_tx.saPayloadLen=len-14-20; //don't include tag, mac and outer header //meta_tx.startOffset = 0; meta_tx.startOffset = p_sa_info->tx_pkt_info.startOffset; //meta_tx.ipOffBytes = 14+20+8+16; //to inner header meta_tx.ipOffBytes =p_sa_info->tx_payload_info.encOffset; //meta_tx.l4OffBytes = 14+20+8+16+20; //to L4 meta_tx.l4OffBytes = p_sa_info->tx_pkt_info.l4OffBytes; meta_tx.l4HdrLen = p_sa_info->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.pseudoHdrChecksum = test_utilGetIpv4PsudoChkSum(&p_pkt[meta_tx.ipOffBytes],8+ meta_tx.ploadLen); /* post it to netcp tx channel*/ meta.u.tx_meta=&meta_tx; if (stats.sec_tx<20) dump_descr((long *) tip, stats.sec_tx); pktio_send(netcp_tx_chan,tip,&meta,&err); stats.tx +=1; stats.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_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ); meta_tx2.startOffset = 0; meta_tx2.ipOffBytes = 14; meta_tx2.l4OffBytes = 14+20; meta_tx2.l4HdrLen = 8; meta_tx2.ploadLen = (unsigned) ((p_pkt[14+20+4]<<8)|p_pkt[14+20+4+1]) -8 ; meta_tx2.pseudoHdrChecksum = test_utilGetIpv4PsudoChkSum(&p_pkt[14],8+ meta_tx2.ploadLen); /* post it to netcp tx channel*/ meta2.u.tx_meta=&meta_tx2; pktio_send(netcp_tx_chan,tip,&meta2,&err); stats.tx +=1; } } /*************************************** benchmark receive handler ****************************************/ void recv_cb_bench(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[], PKTIO_METADATA_T meta[], int n_pkts, uint64_t ts ) { int i; vv6= netapi_timing_stop(); for (i=0;iappId == p_sa_info->rx_tunnel) { time = netapi_timing_start(); delta_time = time -(unsigned long) meta[i].u.rx_sb_meta->appCtxId; stats.total_decrypt_time += delta_time; stats.sb_rx+=1; //copy hash out of meta data (for some reason it needs endian conversion) hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]); hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]); hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]); if(stats.sb_rx<=16) { char *tp = (char *) &hash[0]; //dump_header((long*)p_pkt, stats.sb_rx, (int)meta[i].u.rx_sb_meta->appId,0); #if 0 printf("tag in pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n", p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8], p_pkt[len-7],p_pkt[len-6], p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]); printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n", tp[0],tp[1],tp[2],tp[3],tp[4],tp[5], tp[6],tp[7],tp[8],tp[9],tp[10],tp[11]); #endif } //check tag tag_cmp = memcmp(&p_pkt[len-12],(char*) &hash[0],12); //todo, really use meta->authTagLen stats.n_auth_ok += !(tag_cmp); flip_and_send_pkt(tip, p_pkt, len,1); //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]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]); hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]); hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]); stats.sb_tx+=1; if(stats.sb_tx<=16) { char *tp1 = (char *) &hash[0]; //dump_header((long*)p_pkt, stats.sb_tx, (int)meta[i].u.rx_sb_meta->appId,0); #if 0 printf("tag in original rx pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n", p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8], p_pkt[len-7],p_pkt[len-6], p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]); printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n", tp1[0],tp1[1],tp1[2],tp1[3],tp1[4],tp1[5], tp1[6],tp1[7],tp1[8],tp1[9],tp1[10],tp1[11]); #endif } //put the computed tag in the packet memcpy(&p_pkt[len-12],(char*)&hash[0],12); //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; //not used meta_tx.l4OffBytes = 0; meta_tx.l4HdrLen = 0; meta_tx.ploadLen = 0; time = netapi_timing_start(); delta_time = time -(unsigned long) meta[i].u.rx_sb_meta->appCtxId; stats.total_encrypt_time += delta_time; /* post it to netcp tx channel*/ meta2.u.tx_meta=&meta_tx; pktio_send(netcp_tx_chan,tip,&meta2,&err); stats.tx +=1; } } else printf("netapi recv_sb_cb: unknown appiD %x \n",meta[i].u.rx_sb_meta->appId ); } } /******************************************************/ /******************PKT RECEIVE HANDLER *************************/ /******************************************************/ 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; HEAD_T * p_res; Ti_Pkt * tip; unsigned int templen; int err; KEY_T key; char * p_pkt; HEAD_T * p_head; HEAD_T temp_head; netTestSA_t *p_sa_info; uint8_t *p_spi; uint8_t p_iv[16]; p_head=&temp_head; //debug #if 0 if (n_pkts != TX_BURST) { printf("recv_cb, txsofar=%d rxsofar=%d np = %d, NOT %d\n", stats.itx, stats.rx, n_pkts,TX_BURST); our_stats_cb(netapi_handle,NULL); } #endif //test_alloc_free(7); //printf("recv start\n"); /* loop over received pkts */ for(i=0;irx dmp.."); dump_descr((long *) tip, stats.rx); } else if (stats.rx>99) { printf(">rx dmp.."); dump_descr((long *) tip,stats.rx); } #endif #if 0 if(stats.rx<=16) { dump_header((long*)p_pkt, stats.rx, (int)meta[i].u.rx_meta->appId,meta[i].u.rx_meta->rxFlag1); } #endif /* check header */ memcpy(p_head,&p_pkt[14],sizeof(HEAD_T)); if ((p_head->ip[2]&0x0000ff00)==0x00003200) { if (!check_header(p_head,&meta[i])) { stats.n_bad+=1;Pktlib_freePacket(tip); continue; } //process IP SEC PACKET if (config.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, (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=p_sa_info->rx_data_mode_handle; memcpy(&meta_tx, &(p_sa_info->tx_payload_info), sizeof(nwalDmTxPayloadInfo_t)); meta_tx.ploadLen = len; meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -netTest_ICV_LEN; meta_tx.authSize = len - meta_tx.authOffset - netTest_ICV_LEN; meta_tx.encIvSize = p_sa_info->tx_payload_info.encIvSize; #if 0 printf("recv_cb(): encOffset %d\n", meta_tx.encOffset); printf("recv_cb():authOffset %d\n", meta_tx.authOffset); printf("recv_cb(): encSize %d\n", meta_tx.encSize); printf("recv_cb(): authSize %d\n", meta_tx.authSize); printf("recv_cb(): encIvSize %d\n", meta_tx.encIvSize); #endif if (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CTR) { memcpy(&p_iv[0], &ourEncrKey[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_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 = netapi_timing_start(); //printf("recv_cb appCtxId: %lu\n", meta_tx.appCtxId); /* post it to netcp sb tx channel*/ meta2.u.tx_sb_meta=&meta_tx; pktio_send(netcp_sb_tx_chan,tip,&meta2,&err); continue; } else //inflow mode. flip and send flip_and_send_pkt(tip,p_pkt,len,1); } else if ((p_head->ip[2]&0x0000ff00)!=0x00001100) { stats.n_new+=1;Pktlib_freePacket(tip); continue; } else //non ipsec { if (!check_header(p_head,&meta[i])) { stats.n_bad+=1;Pktlib_freePacket(tip); continue; } #if 0 /* lookup flow */ key.src_ip = p_head->ip[3]; key.dst_ip = p_head->ip[4]; key.src_port= (p_head->udp[0]&0xffff0000)>>16; key.dst_port= (p_head->udp[0]&0x0000ffff); p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key)); if (!p_res) { stats.n_new+=1; slow_path(tip, len); continue;} /* copy header */ memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T)); memcpy(&p_pkt[14],p_head,sizeof(HEAD_T)); /* update_mac(&p_pkt[0]); */ /* 'simulate' send pkt */ send_pkt(tip,len); #endif //just flip and send flip_and_send_pkt(tip,p_pkt,len,0); } } //printf("recv done\n"); } //timer callback void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th, int n_fired, //# timers fired NETAPI_TIMER_LIST_T fired_list, uint64_t currentTime) { int i; NETAPI_TIMER_T tx; int cookie; int err; unsigned long long et; //DEBUGprintf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired); tx = netapi_TimerGetFirst(fired_list); for(i=0;ipktEncHi) ||(p_saIpsecStats->pktEncLo)) { printf("------------- IPSec TX (Encryption Channel) Stats BEGIN --\n"); } else { printf("------------- IPSec RX (Decryption Channel) Stats BEGIN --\n"); } #endif printf("\nAutentication mode: %d, Encryption Mode: %d\n", auth, cipher); printf("IPSec replayOld:0x%x,replayDup:0x%x,authFail:0x%x \n", p_saIpsecStats->replayOld,p_saIpsecStats->replayDup,p_saIpsecStats->authFail); printf("IPSec txESN:0x%x,rxESN:0x%x,pktEncHi:0x%x,pktEncLo:0x%x,pktDecHi:0x%x,pktDecLo:0x%x \n", p_saIpsecStats->txESN,p_saIpsecStats->rxESN,p_saIpsecStats->pktEncHi, p_saIpsecStats->pktEncLo,p_saIpsecStats->pktDecHi,p_saIpsecStats->pktDecLo); printf("------------- IPSec Stats END ----------------------------\n\n"); } void print_datamode_stats(Sa_DataModeStats_t *p_saDataModeStats, nwal_saAALG auth, nwal_saEALG cipher) { printf("\nAutentication mode: %d, Encryption Mode: %d\n", auth, cipher); printf(" Packets processedHi: 0x%x, Packets processed Lo:0x%x\n", p_saDataModeStats->pktHi, p_saDataModeStats->pktLo); } static int np2process = NP; /****************************************************** * stats callback *******************************************************/ void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats) { uint32_t numFreeDataPackets; uint32_t numZeroBufferPackets; uint32_t numPacketsinGarbage; Pktlib_HeapStats pktLibHeapStats; int i; unsigned long long bcpp; unsigned long long bcpp_noc; unsigned long long bcpp_app; unsigned long long bcpp_tx; unsigned long long npL; unsigned long long cyclesL; unsigned long long ccyclesL; //cache cycles NETAPI_SA_STATS_T netapi_sa_stats; printf(">*****stats @ %lld\n", netapi_getTimestamp()); //printf("netcp_tx_handle check %x\n", netcp_tx_chan->back); printf(">itx=%d rx=%d tx=%d bad=%d slow=%d \n>rx_class0=%d rx_class1=%d rx_class2=%d secRx=%d secPRX=%d sb_rx=%d sb_tx=%d auth_ok=%d sec_tx=%d\n", stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new, stats.n_class0_rx, stats.n_class1_rx, stats.n_class2_rx, stats.sec_rx, stats.secp_rx, stats.sb_rx, stats.sb_tx, stats.n_auth_ok, stats.sec_tx); if (stats.rx && stats.tx) printf("decrypt time per packet(avg): %lu, encrypt time per packet(avg): %lu\n", (unsigned long) stats.total_decrypt_time/stats.rx, (unsigned long) stats.total_encrypt_time/stats.tx); netapi_sched_get_stats(&npL,&cyclesL,&ccyclesL); if (npL && stats.rx) { bcpp = cyclesL/npL; bcpp_noc = (cyclesL-ccyclesL)/npL; bcpp_app = (stats.app_cycles-stats.tx_cache_cycles)/stats.rx; } else {bcpp = bcpp_noc=bcpp_app=0L;} if (stats.tx) { bcpp_tx = (stats.send_cycles-stats.tx_cache_cycles)/stats.tx; }else {bcpp_tx = 0L;} printf("> ++ busy cycles pp=%lld (%lld wo cache ops) (app+tx= %lld) (tx= %lld) ++\n", bcpp,bcpp_noc,bcpp_app, bcpp_tx); if(pPaStats) { printf("C1 number of packets: %d\n", pPaStats->classify1.nPackets); printf("C1 number IPv4 packets: %d\n", pPaStats->classify1.nIpv4Packets); printf("C1 number IPv6 packets: %d\n", pPaStats->classify1.nIpv6Packets); printf("C1 number Custom packets: %d\n", pPaStats->classify1.nCustomPackets); printf("C1 number SRIO packets: %d\n", pPaStats->classify1.nSrioPackets); printf("C1 number LLC/SNAP Fail packets: %d\n", pPaStats->classify1.nLlcSnapFail); printf("C1 number table matched: %d\n", pPaStats->classify1.nTableMatch); printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch); printf("C1 number IP Fragmented packets: %d\n", pPaStats->classify1.nIpFrag); printf("C1 number IP Depth Overflow: %d\n", pPaStats->classify1.nIpDepthOverflow); printf("C1 number VLAN Depth Overflow: %d\n", pPaStats->classify1.nVlanDepthOverflow); printf("C1 number GRE Depth Overflow: %d\n", pPaStats->classify1.nGreDepthOverflow); printf("C1 number MPLS Packets: %d\n", pPaStats->classify1.nMplsPackets); printf ("C1 number of parse fail: %d\n",pPaStats->classify1.nParseFail); printf("C1 number of Invalid IPv6 Opt: %d\n", pPaStats->classify1.nInvalidIPv6Opt); printf("C1 number of TX IP Fragments: %d\n", pPaStats->classify1.nTxIpFrag); printf ("C1 number of silent discard: %d\n",pPaStats->classify1.nSilentDiscard); printf("C1 number of invalid control: %d\n", pPaStats->classify1.nInvalidControl); printf ("C1 number of invalid states: %d\n",pPaStats->classify1.nInvalidState); printf ("C1 number of system fails: %d\n",pPaStats->classify1.nSystemFail); printf ("C2 number Packets : %d\n",pPaStats->classify2.nPackets); printf ("C2 number udp : %d\n",pPaStats->classify2.nUdp); printf ("C2 number tcp : %d\n",pPaStats->classify2.nTcp); printf ("C2 number Custom : %d\n",pPaStats->classify2.nCustom); printf ("C2 number silent drop : %d\n",pPaStats->classify2.nSilentDiscard); printf ("C2 number invalid cntrl : %d\n\n",pPaStats->classify2.nInvalidControl); printf ("C2 number Modify Stats Cmd Fail : %d\n\n",pPaStats->modify.nCommandFail); } Pktlib_getHeapStats(OurHeap, &pktLibHeapStats); printf("main heap stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets, pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage); printf(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter, pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter); Pktlib_getHeapStats(specialSmall, &pktLibHeapStats); printf("specialSmall heap stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets, pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage); printf(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter, pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter); Pktlib_getHeapStats(specialLarge, &pktLibHeapStats); printf("specialLarge heap stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets, pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage); printf(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter, pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter); #if 0 printf("pa2sa descriptor area dump\n"); for(i=0;i request stats at n=%d \n",house_pkts_gened); netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err); if (err!=0) {printf("stats req failed\n");} if (house_pkts_gened >= np2process+ 100) { netapi_schedShutdown(s,NULL,&err); } return; } done_burst=1; Osal_cache_op_measure_reset(); memset(&meta_tx,0,sizeof(meta_tx)); for(p=0;p0) && (! (house_pkts_gened%1000)) ) { printf("net_test> request stats at n=%d \n",house_pkts_gened); netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err); if (err!=0) {printf("stats req failed\n");} } if (house_pkts_gened >= np2process+ 100) { //shutdown netapi_schedShutdown(s,NULL,&err); continue; } else if (house_pkts_gened >= np2process) { house_pkts_gened+=1; continue;} /* manufacture a pkt to transmit */ tip = get_pkt(house_pkts_gened, &len, OurHeap, PKT_LEN,&testPkt[0] , TEST_PKT_LEN); if(!tip) { house_pkts_gened +=1; continue; } /* set the pkt length */ vv1 = netapi_timing_start(); Pktlib_setPacketLen(tip, len); /* set up meta data */ meta.sa_handle=nwal_HANDLE_INVALID; //#define BENCH_UDP_SEND #ifdef BEND_UDP_SEND meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID); meta_tx.startOffset = 0; //GONE in V2 meta_tx.pktLen = len; meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES; meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES; meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN; //GONE in V2 meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES; meta_tx.ploadLen = TEST_PAYLOAD_LEN; Pktlib_getDataBuffer(tip,&pData,&len); if(house_pkts_gened &0x1) { memcpy(&pData[6],&config.mac1[0] ,6); } pIpHdr = pData + meta_tx.ipOffBytes; meta_tx.pseudoHdrChecksum = test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN)); #else Pktlib_getDataBuffer(tip,&pData,&len); if(house_pkts_gened &0x1) { memcpy(&pData[6],&config.mac1[0] ,6); } meta_tx.txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID; meta_tx.startOffset = 0; meta_tx.ploadLen = TEST_PAYLOAD_LEN; #endif /* post it to netcp tx channel*/ meta.u.tx_meta=&meta_tx; #ifdef DEBUG_DESC if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened); else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened); #endif if(!first) { first++; nwal_flow_vv1= netapi_timing_stop(); if(nwal_initPSCmdInfo(PKTIO_GET_NWAL_INSTANCE(netcp_tx_chan), &meta_tx, &flowPSCmdInfo) != nwal_OK) { printf("nwal_initPSCmdInfo() ERROR \n"); } nwal_flow_vv2= netapi_timing_stop(); nwal_sum_flow_vv1 += (nwal_flow_vv1-vv1); nwal_sum_flow_vv2 += (nwal_flow_vv2-nwal_flow_vv1); } cache_op_b1= Osal_cache_op_measure(&n_c_ops); vv2= netapi_timing_stop(); #ifdef BEND_UDP_SEND nwal_mCmdSetL4CkSumPort( tip, &flowPSCmdInfo, TEST_PKT_UDP_OFFSET_BYTES, (TEST_PKT_UDP_HDR_LEN + TEST_PAYLOAD_LEN), meta_tx.pseudoHdrChecksum, meta_tx.enetPort); #else nwal_mCmdSetPort (tip, &flowPSCmdInfo, //could be NULL 0); //port 0 -> switch decides #endif pPktDesc = Pktlib_getDescFromPacket(tip); /* Send the packet out to transmit Q*/ Qmss_queuePushDescSize (flowPSCmdInfo.txQueue, pPktDesc, NWAL_DESC_SIZE); vv3= netapi_timing_stop(); cache_op_b2= Osal_cache_op_measure(&n_c_ops); sum_vv1 += (vv2-vv1); if(!house_pkts_gened) { /* first packet. Take out the PS command label creation cost */ sum_vv1 = sum_vv1 - nwal_sum_flow_vv2; } sum_vv3 += (vv3-vv2)-(cache_op_b2-cache_op_b1); //sub out cache op cost // printf("pktio send. full=%d metadata=%d pktio_send=%d\n", vv3-vv1, vv2-vv1, vv3-vv2); stats.itx +=1; house_pkts_gened +=1; } { unsigned int ccycles; ccycles =Osal_cache_op_measure(&n_c_ops); if (sum_vv1) { printf("BURST NWAL Fast send %d pkts. metadata=%d Cmd Label Creation Cost=%d nwal Fast Send Cost (less cacheop)= %d n_c_ops=%d cache_op_time=%d (pp-> %d)\n", stats.itx, sum_vv1/stats.itx, nwal_sum_flow_vv2, sum_vv3/stats.itx, n_c_ops, ccycles, n_c_ops? (ccycles/(n_c_ops/2)) : 0); #if 0 printf("NWAL Profile Cycles: Prof1= %d,Prof2=%d,Prof3=%d,Prof4=%d,Prof5=%d ,Prof6=%d \n", nwal_sum_vv1/stats.itx,nwal_sum_vv2/stats.itx,nwal_sum_vv3/stats.itx, nwal_sum_vv4/stats.itx,nwal_sum_vv5/stats.itx,nwal_sum_vv6/stats.itx); #endif if(stats.itx2) { printf("nwal_flowSend Profile Cycles: Prof1= %d,Prof2=%d \n", nwal_sum_flow_vv1/stats.itx2,nwal_sum_flow_vv2/stats.itx2); } } } } void build_sa_db(int i) { if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_SHA1) && (tx_sa[i].cipherMode == NWAL_SA_EALG_AES_CBC)) { /* static configuration, will not change */ sa_info[i].tx_payload_info.aadSize = 0; sa_info[i].tx_payload_info.pAad = NULL; sa_info[i].tx_payload_info.authIvSize = 0; sa_info[i].tx_payload_info.pAuthIV = NULL; sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN; /*done: same for all cipher suites */ sa_info[i].tx_payload_info.encIvSize = netTest_AES_CBC_IV_LEN; sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN + netTest_AES_CBC_IV_LEN; /* dynamic configuration, will be calculated on the fly */ sa_info[i].tx_payload_info.authSize = 0; /* pkt len - mac - ip -icv (12) */ sa_info[i].tx_payload_info.encSize = 0; /* authSize - esp header size (always 8 bytes) */ sa_info[i].tx_payload_info.ploadLen = 0; /* will be packet length */ sa_info[i].tx_payload_info.pEncIV = 0; sa_info[i].tx_payload_info.pPkt = 0; /* not being referenced in net_test */ sa_info[i].cipherMode = NWAL_SA_EALG_AES_CBC; sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset; sa_info[i].auth_tag_size = netTest_ICV_LEN; /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */ #ifdef EXPERIMENTAL sa_info[i].iv_len=16; sa_info[i].bl=16; sa_info[i].spi = tx_sa[i].spi; sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0])); sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0])); #endif sa_info[i].tx_pkt_info.enetPort = 0; sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset; sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */ sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN; sa_info[i].tx_pkt_info.startOffset = 0; sa_info[i].tx_pkt_info.lpbackPass = 0; sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */ sa_info[i].tx_pkt_info.pPkt = NULL; sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN; sa_info[i].tx_pkt_info.saPayloadLen = 0; sa_info[i].tx_pkt_info.pseudoHdrChecksum =0; sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ; trie_insert(p_trie_sa,(char *)&(tx_sa[i].spi),4, (void *) &sa_info[i]); //asociate with tx sa SPI } else if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_SHA2_256) && (tx_sa[i].cipherMode == NWAL_SA_EALG_AES_CTR)) { printf("inside build_sa_db, index %d\n", i); /* static configuration, will not change */ sa_info[i].tx_payload_info.aadSize = 0; sa_info[i].tx_payload_info.pAad = NULL; sa_info[i].tx_payload_info.authIvSize = 0; sa_info[i].tx_payload_info.pAuthIV = NULL; sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN; /*done: same for all cipher suites */ sa_info[i].tx_payload_info.encIvSize = netTest_AES_CTR_IV_CONTEXT_LEN; sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN + netTest_AES_CTR_IV_PACKET_LEN; /* dynamic configuration, will be calculated on the fly */ sa_info[i].tx_payload_info.authSize = 0; sa_info[i].tx_payload_info.encSize = 0; sa_info[i].tx_payload_info.ploadLen = 0; sa_info[i].tx_payload_info.pEncIV = 0; sa_info[i].tx_payload_info.pPkt = 0; sa_info[i].cipherMode = NWAL_SA_EALG_AES_CTR; sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset; sa_info[i].auth_tag_size = netTest_ICV_LEN; /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */ #ifdef EXPERIMENTAL sa_info[i].iv_len=8; sa_info[i].bl=8; sa_info[i].spi = tx_sa[i].spi; sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0])); sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0])); #endif sa_info[i].tx_pkt_info.enetPort = 0; sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset; sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */ sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN; sa_info[i].tx_pkt_info.startOffset = 0; sa_info[i].tx_pkt_info.lpbackPass = 0; sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */ sa_info[i].tx_pkt_info.pPkt = NULL; sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN; sa_info[i].tx_pkt_info.saPayloadLen = 0; sa_info[i].tx_pkt_info.pseudoHdrChecksum =0; sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ; trie_insert(p_trie_sa,(char *)&(tx_sa[i].spi),4, (void *) &sa_info[i]); //asociate with tx sa SPI } else if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_SHA2_256) && (tx_sa[i].cipherMode == NWAL_SA_EALG_3DES_CBC)) { /* static configuration, will not change */ sa_info[i].tx_payload_info.aadSize = 0; sa_info[i].tx_payload_info.pAad = NULL; sa_info[i].tx_payload_info.authIvSize = 0; sa_info[i].tx_payload_info.pAuthIV = NULL; sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN; /*done: same for all cipher suites */ sa_info[i].tx_payload_info.encIvSize = netTest_3DES_CBC_IV_LEN; sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN + netTest_3DES_CBC_IV_LEN; /* dynamic configuration, will be calculated on the fly */ sa_info[i].tx_payload_info.authSize = 0; sa_info[i].tx_payload_info.encSize = 0; sa_info[i].tx_payload_info.ploadLen = 0; sa_info[i].tx_payload_info.pEncIV = 0; sa_info[i].tx_payload_info.pPkt = 0; sa_info[i].cipherMode = NWAL_SA_EALG_3DES_CBC; sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset; sa_info[i].auth_tag_size = netTest_ICV_LEN; /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */ #ifdef EXPERIMENTAL sa_info[i].iv_len=8; sa_info[i].bl=8; sa_info[i].spi = tx_sa[i].spi; sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0])); sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0])); #endif sa_info[i].tx_pkt_info.enetPort = 0; sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset; sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */ sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN; sa_info[i].tx_pkt_info.startOffset = 0; sa_info[i].tx_pkt_info.lpbackPass = 0; sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */ sa_info[i].tx_pkt_info.pPkt = NULL; sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN; sa_info[i].tx_pkt_info.saPayloadLen = 0; sa_info[i].tx_pkt_info.pseudoHdrChecksum =0; sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ; trie_insert(p_trie_sa,(char *)&(tx_sa[i].spi),4, (void *) &sa_info[i]); //asociate with tx sa SPI } else if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_MD5) && (rx_sa[i].cipherMode == NWAL_SA_EALG_NULL)) { /* static configuration, will not change */ sa_info[i].tx_payload_info.aadSize = 0; sa_info[i].tx_payload_info.pAad = NULL; sa_info[i].tx_payload_info.authIvSize = 0; sa_info[i].tx_payload_info.pAuthIV = NULL; sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN; /*done: same for all cipher suites */ sa_info[i].tx_payload_info.encIvSize = netTest_NULL_IV_LEN; sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN + netTest_NULL_IV_LEN; #ifdef EXPERIMENTAL sa_info[i].iv_len=0; sa_info[i].bl=4; sa_info[i].spi = tx_sa[i].spi; sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0])); sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0])); #endif /* dynamic configuration, will be calculated on the fly */ sa_info[i].tx_payload_info.authSize = 0; sa_info[i].tx_payload_info.encSize = 0; sa_info[i].tx_payload_info.ploadLen = 0; sa_info[i].tx_payload_info.pEncIV = 0; sa_info[i].tx_payload_info.pPkt = 0; sa_info[i].cipherMode = NWAL_SA_EALG_NULL; sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset; sa_info[i].auth_tag_size = netTest_ICV_LEN; /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */ sa_info[i].tx_pkt_info.enetPort = 0; sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset; sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */ sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN; sa_info[i].tx_pkt_info.startOffset = 0; sa_info[i].tx_pkt_info.lpbackPass = 0; sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */ sa_info[i].tx_pkt_info.pPkt = NULL; sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN; sa_info[i].tx_pkt_info.saPayloadLen = 0; sa_info[i].tx_pkt_info.pseudoHdrChecksum =0; sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ; trie_insert(p_trie_sa,(char *)&(tx_sa[i].spi),4, (void *) &sa_info[i]); //asociate with tx sa SPI } else printf("build_sa_db(): invalid encryption/authentication combination selected\n"); //printf("sa_build_db(): authOffset %d, innerIpOffset %d, encOffset %d\n", sa_info[i].tx_payload_info.authOffset, sa_info[i].inner_ip_offset, sa_info[i].tx_payload_info.encOffset); } #define CHECK_SET_PARAM(ARG1, ARG2) \ do { \ if(strcmp(key, ARG1) == 0) { \ if(data)strncpy(ARG2,data,CONFIG_STRING_LEN); \ printf("CHECK_SET_PARM, match found, input cong string %s\n", ARG2); \ continue; \ } \ } while(0) #define CHECK_SET_PARAM2(ARG1, ARG2, ARG3) \ do { \ if(strcmp(key, ARG1) == 0) { \ if(data) strncpy(ARG2,data,CONFIG_STRING_LEN); \ if(data2) strncpy(ARG3,data2,CONFIG_STRING_LEN); \ printf("CHECK_SET_PARM, match found, input cong string %s %s\n", ARG2, ARG3); \ continue; \ } \ } while(0) unsigned char hex2dec(char *p_s) { int val; sscanf(p_s,"%x",&val); return val&0xff; } void parse_one_mac(char * p_mac_str, unsigned char *p_mac) { int index = 0; int i; char *pch = strtok (&(p_mac_str[0]),"-"); while (pch != NULL) { printf ("%s\n",pch); p_mac[index] = hex2dec(pch); index++; pch = strtok (NULL,"-"); } printf("index value : %d\n", index); for (i=0; i<6;i++) printf("************mac0[%d]: 0x%x\n",i, p_mac[i]); } void parse_one_ip(char * p_ip_addr_str, unsigned char * p_ip) { int index = 0; int i; char * pch = strtok (&p_ip_addr_str[0],"."); while (pch != NULL) { printf ("xxxxx: %s\n",pch); p_ip[index] = atoi(pch); index++; pch = strtok (NULL,"."); } printf("index value : %d\n", index); for (i=0; i<4;i++) printf("************ip[%d]: 0x%x\n",i, p_ip[i]); } void parse_mac_address(netTestConfigFile_t *pConfig) { if (strlen(&pConfig->mac0[0])) parse_one_mac(&pConfig->mac0[0],&config.mac0[0]); if (strlen(&pConfig->mac1[0])) parse_one_mac(&pConfig->mac1[0],&config.mac1[0]); } void parse_ip_address(netTestConfigFile_t *pConfig) { if (strlen(&pConfig->ip0[0])) parse_one_ip(&pConfig->ip0[0],&config.ip0.ipv4[0]); if (strlen(&pConfig->ip1[0])) parse_one_ip(&pConfig->ip1[0],&config.ip1.ipv4[0]); if (strlen(&pConfig->ip2[0])) parse_one_ip(&pConfig->ip2[0],&config.ip2.ipv4[0]); if (strlen(&pConfig->local_ipsec_ip[0])) parse_one_ip(&pConfig->local_ipsec_ip[0],&config.local_ipsec_ip.ipv4[0]); if (strlen(&pConfig->remote_ipsec_ip[0])) parse_one_ip(&pConfig->remote_ipsec_ip[0],&config.remote_ipsec_ip.ipv4[0]); } void parse_ipsec_mode(netTestConfigFile_t *pConfig) { printf("parse_ipsec_mode, string length %d\n", strlen(&pConfig->ipsec_mode_rx)); if (strlen(&pConfig->ipsec_mode_rx[0])) { if (strcmp(pConfig->ipsec_mode_rx, "SIDEBAND") == 0) { config.ipsec_mode_rx = IPSEC_MODE_RX_SIDEBAND; } else if (strcmp(pConfig->ipsec_mode_rx, "INFLOW") == 0) { config.ipsec_mode_rx = IPSEC_MODE_RX_INFLOW; } else printf("parse_ipsec_mode(), invalid RX ipsec mode in config file \n"); } if (strlen(&pConfig->ipsec_mode_tx[0])) { if (strcmp(pConfig->ipsec_mode_tx, "SIDEBAND") == 0) { config.ipsec_mode_tx = IPSEC_MODE_TX_SIDEBAND; } else if (strcmp(pConfig->ipsec_mode_tx, "INFLOW") == 0) { config.ipsec_mode_tx = IPSEC_MODE_TX_INFLOW; } else printf("parse_ipsec_mode(), invalid TX ipsec mode in config file \n"); } printf("parse_ipsec_mode(): RX mode %d\n", config.ipsec_mode_rx); printf("parse_ipsec_mode(): TX mode %d\n", config.ipsec_mode_tx); } #ifdef EXPERIMENTAL int n_routes=0; int n_dst_ips=0; void parse_routes(netTestConfigFile_t *pConfig) { int i; int said=0; for(i=0;iroutes[i][0]) { port=atoi(&pConfig->ports[i][0]); if((port<1)||(port>2)) continue; //bad port #: only 1 or 2 valid if(strncmp(&pConfig->routes[i][0],"MAC",3)==0) { routes[i].out_port = port; parse_one_mac(&pConfig->routes[i][3],&routes[i].out_mac[0]); memcpy(&routes[i].out_mac[6], ((port==1) ?&config.mac0[0]: &config.mac1[0] ),6); routes[i].out_mac[12]=0x08; routes[i].out_mac[13]=0x00; routes[i].sec_ptr=NULL; n_routes+=1; } else if (strncmp(&pConfig->routes[i][0],"SA",2)==0) { said=atoi(&pConfig->routes[i][2]) ; routes[i].sec_ptr=&sa_info[said]; n_routes+=1; } } } our_router = route_init(); for (i=0;idst_ips[i][0]) { parse_one_ip(&pConfig->dst_ips[i][0],(unsigned char *)&ip_be); sscanf(&pConfig->paths[i][0],"route%d",&route_index); route_add(our_router,&ip_be,&routes[route_index]); n_dst_ips+=1; } } printf(">Route DB built. %d entries\n",n_dst_ips); } #endif static void parse_config_file(FILE * fpr, netTestConfigFile_t *pConfig) { char line[MAX_LINE_LENGTH + 1]; int i; char *key, *data, *ep, *data2; char tokens[] = " :=;\n"; char temp_str[50]; memset(line, 0, MAX_LINE_LENGTH + 1); memset(pConfig, 0, sizeof(netTestConfigFile_t)); while (fgets(line, MAX_LINE_LENGTH + 1, fpr)) { if(line[0]=='#') continue; //skip comment key = (char *)strtok(line, tokens); data = (char *)strtok(NULL, tokens); data2 = (char *)strtok(NULL, tokens); if (!key) continue; if (!data) continue; if(strlen(data) == 0) { continue; } CHECK_SET_PARAM(INIT_CONFIG_MAC0,&(pConfig->mac0[0])); CHECK_SET_PARAM(INIT_CONFIG_MAC1,&(pConfig->mac1[0])); CHECK_SET_PARAM(INIT_CONFIG_IP0,&(pConfig->ip0[0])); CHECK_SET_PARAM(INIT_CONFIG_IP1,&(pConfig->ip1[0])); CHECK_SET_PARAM(INIT_CONFIG_IP2,&(pConfig->ip2[0])); CHECK_SET_PARAM(INIT_CONFIG_LOCAL_IPSEC_IP,&(pConfig->local_ipsec_ip[0])); CHECK_SET_PARAM(INIT_CONFIG_REMOTE_IPSEC_IP,&(pConfig->remote_ipsec_ip[0])); CHECK_SET_PARAM(INIT_CONFIG_IPSEC_MODE_RX,&(pConfig->ipsec_mode_rx[0])); CHECK_SET_PARAM(INIT_CONFIG_IPSEC_MODE_TX,&(pConfig->ipsec_mode_tx[0])); CHECK_SET_PARAM(INIT_CONFIG_IPSEC_IF_NO,&(pConfig->ipsec_if_no[0])); #ifdef EXPERIMENTAL for(i=0;iroutes[i][0],&pConfig->ports[i][0] ); } for(i=0;idst_ips[i][0],&pConfig->paths[i][0] ); } #endif } parse_mac_address(pConfig); parse_ip_address(pConfig); parse_ipsec_mode(pConfig); #ifdef EXPERIMENTAL if (strlen(&pConfig->ipsec_if_no[0])) config.ipsec_if_no = atoi(&pConfig->ipsec_if_no[0]); parse_routes(pConfig); #endif } static netTestConfigFile_t config_file; /*************************************** ********** test driver***************** ***************************************/ int main(int argc, char **argv) { int err,i; rlim_t oss,ss = 1024*1024; struct rlimit rl; Pktlib_HeapCfg heapCfg; int32_t errCode; Pktlib_HeapIfTable* pPktifTable; FILE * fpr = NULL; err= getrlimit(RLIMIT_STACK,&rl); if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n"); #if 0 rl.rlim_cur = ss; err=setrlimit(RLIMIT_STACK,&rl); i f (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n"); #endif if (argc>=2) np2process = atoi(argv[1]); printf("*************** np2process %d\n", np2process); if (np2process<0) np2process = NP; /* default */ if (argc==3) perslow = atoi(argv[2]); if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default if (argc>3) {printf("net_test \n"); exit(1);} #if 1 #if 0 if (argc >= 2) { fpr = fopen(argv[2], "r"); if (fpr == NULL) { printf("Error in opening %s input file\n", argv[2]); } } else #endif { fpr = fopen(input_file_name, "r"); if (fpr == NULL) { printf("Error in opening %s input file\n", input_file_name); } else { parse_config_file(fpr,&config_file); } } #endif memset(&sa_info, 0, sizeof(sa_info)); //real mode, so update our test packet mac header and ip header if (pktloopback==0) { memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses } #if 0 our_router = route_init(); for (i=0;idata_malloc; heapCfg.heapInterfaceTable.data_free = pPktifTable->data_free; heapCfg.dataBufferPktThreshold = 0; heapCfg.zeroBufferPktThreshold = 0; specialSmall = Pktlib_createHeap(&heapCfg, &errCode); heapCfg.name = "netapi-big"; heapCfg.dataBufferSize = 1600; specialLarge = Pktlib_createHeap(&heapCfg, &errCode); //register these heaps so poll routine will include their garbage queues. netapi_registerHeap(netapi_handle, specialSmall); netapi_registerHeap(netapi_handle, specialLarge); #ifdef REASSEMBLE_BENCH our_reassemble_bench(2); exit(1); #endif #ifndef EXPERIMENTAL /* create a pktio channel */ our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb_bench, &our_chan_cfg,&err); if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);} #endif /* open netcp default tx, rx queues */ netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err); if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);} #ifdef EXPERIMENTAL netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg, &err); #else netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg, &err); #endif if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);} #ifndef EXPERIMENTAL /* create a pktio channel for specially classified pkts */ netcp_rx_chan2= pktio_create(netapi_handle, "classq", (PKTIO_CB) recv_cb, &netcp_rx_cfg2, &err); if (!netcp_rx_chan2) {printf("pktio create RX2 failed err=%d\n",err); exit(1);} /* open netcp default tx, rx queues for sideband crypto */ netcp_sb_tx_chan= pktio_open(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);} netcp_sb_rx_chan= pktio_open(netapi_handle, NETCP_SB_RX, (PKTIO_CB) recv_sb_cb, &netcp_sb_rx_cfg, &err); if (!netcp_sb_rx_chan) {printf("pktio open SB RX failed err=%d\n",err); exit(1);} #endif printf("net_test> %d bytes left in our CMA area\n", netapi_getBufMemRemainder()); /* create scheduler instance */ our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err); if (!our_sched) {printf("sched create failed\n"); exit(1);} #if 0 /******************************************** * Basic pkt loopback test *********************************************/ printf("...running pure push/pop benchmark\n"); our_pktio_bench(1000); our_pktio_bench(1000); our_pktio_bench(1000); our_pktio_bench(1000); our_pktio_bench(1000); /*********************************************/ #endif /* add mac intefaces */ netcp_cfgCreateMacInterface( netapi_handle, &config.mac0[0], 0,0, (NETCP_CFG_ROUTE_HANDLE_T) NULL, (NETCP_CFG_VLAN_T ) NULL , //future 1, &err); if (err) {printf("addmac0 failed %d\n",err); exit(1); } //attach an IP to this interface ip_rule0=netcp_addIp( netapi_handle, 0, nwal_IPV4, &config.ip0, NULL, //all IP (NETCP_CFG_ROUTE_HANDLE_T) NULL, &err ); if (err) {printf("addip0 failed %d\n",err); exit(1); } //create a 2nd mac instance netcp_cfgCreateMacInterface( netapi_handle, &config.mac1[0], 1,1, (NETCP_CFG_ROUTE_HANDLE_T) NULL, (NETCP_CFG_VLAN_T ) NULL , //future 1, &err); if (err) {printf("addmac1 failed %d\n",err); exit(1); } //attach an IP to this interface ip_rule1=netcp_addIp( netapi_handle, 1, nwal_IPV4, &config.ip1, NULL, //all IP (NETCP_CFG_ROUTE_HANDLE_T) NULL, &err ); if (err) {printf("addip1 failed %d\n",err); exit(1); } #ifndef EXPERIMENTAL //attach 2 classifiers to iface 0, ip0 class_0_cfg.u.c_l4.ip = ip_rule0; class_0 = netcp_cfgAddClass(netapi_handle, &class_0_cfg, NULL, NETCP_CFG_ACTION_TO_SW, &err); if (err) {printf("addclass0 failed %d\n",err); exit(1);} class_1_cfg.u.c_l4.ip = ip_rule0; class_1 = netcp_cfgAddClass(netapi_handle, &class_1_cfg, NULL, NETCP_CFG_ACTION_TO_SW, &err); if (err) {printf("addclass1 failed %d\n",err); exit(1);} //3rd classifier has a different IP and route class_2_cfg.u.c_l3_l4.ip_addr = &config.ip2; //create specialFlow for this classifier { Pktlib_HeapHandle heaps[2]; int sizes[2]; heaps[0]= specialSmall; heaps[1]= specialLarge; #define SPECIAL_SOP_OFF 128 sizes[0]=512-SPECIAL_SOP_OFF; sizes[1]=1600-SPECIAL_SOP_OFF; #if 0 specialFlow = netcp_cfgAddFlow( netapi_handle, 2, heaps, sizes, SPECIAL_SOP_OFF, //offset to start rx is 128 &err); if (err) {printf("add flow failed\n", err); exit(1);} #endif } #if 0 //special route for this classifier: different flow + destination q class2_route.p_dest_q = netcp_rx_chan2; class2_route.p_flow = specialFlow; class_2 = netcp_cfgAddClass(netapi_handle, &class_2_cfg, (void*) &class2_route, NETCP_CFG_ACTION_TO_SW, &err); if (err) {printf("addclass2 failed %d\n",err); exit(1);} #endif #endif //security stuff p_trie_sa = trie_new(); if (!p_trie_sa) {printf("trie alloc for SA failed\n"); exit(1);} for (i=0; i < MAX_SEC_INDEX;i++) { ourRXKeyParams[i].pEncKey = &ourEncrKey[0]; ourRXKeyParams[i].pAuthKey = &ourAuthKey[0]; memcpy(&(rx_sa[i].src), &config.remote_ipsec_ip,4); memcpy(&(rx_sa[i].dst), &config.local_ipsec_ip,4); build_sa_db(i); sa_info[i].rx_tunnel = netapi_secAddSA( netapi_handle, config.ipsec_if_no, //iface #0 &rx_sa[i], &ourRXKeyParams[i], config.ipsec_mode_rx == IPSEC_MODE_RX_SIDEBAND ? NETAPI_SEC_SA_SIDEBAND: NETAPI_SEC_SA_INFLOW, NULL, //use default route &(sa_info[i].rx_data_mode_handle), &(sa_info[i].rx_inflow_mode_handle), &err); if (err) {printf("addRxSa failed %d\n",err); exit(1);} if (config.ipsec_mode_rx == IPSEC_MODE_RX_INFLOW) { //assume inner and outer ip is the same rx_policy[i]= netapi_secAddRxPolicy( netapi_handle, sa_info[i].rx_tunnel, //link to tunnel above 4, //ipv4 &config.remote_ipsec_ip, //src -> them &config.local_ipsec_ip, //dst -> us NULL, // no qualifiers NULL, //default route &err); if (err) {printf("addSaPolicy failed %d, for index %d\n",err,i); exit(1);} } else rx_policy[i] = 0; } //tx SA //security stuff for (i=0; i < MAX_SEC_INDEX;i++) { ourTXKeyParams[i].pEncKey = &ourEncrKey[0]; ourTXKeyParams[i].pAuthKey = &ourAuthKey[0]; memcpy(&(tx_sa[i].src), &config.local_ipsec_ip,4); memcpy(&(tx_sa[i].dst), &config.remote_ipsec_ip,4); sa_info[i].tx_tunnel = netapi_secAddSA( netapi_handle, 0, //iface #0 &(tx_sa[i]), &ourTXKeyParams[i], config.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND ? NETAPI_SEC_SA_SIDEBAND: NETAPI_SEC_SA_INFLOW, NULL, //use default route &(sa_info[i].tx_data_mode_handle), &(sa_info[i].tx_inflow_mode_handle), &err); if (err) {printf("addTxSa failed %d\n",err); exit(1);} } #ifdef TEST_TIMERS //timers ourTimerBlock = netapi_TimerGroupCreate( netapi_handle, "our1sttimer", our_timer_cb, 0, //1 if timers local to thread 0, //1 if expect to cancel netapi_getTicksPerSec()/1000, /* 1 msc resolution for these timers */ netapi_getTicksPerSec()/5000, /* would like .5 msc tolerence */ 10, //small # of timers to test garbage collection &err); if (err) {printf("timergroupcreate failed %d\n",err); exit(1);} //start a couple of timers t1 = netapi_TimerGroupStartTimer( ourTimerBlock, (void *) 1, 100LL, //timer group ticks &err); if (err) {printf("timerstart failed %d\n");} t2 = netapi_TimerGroupStartTimer( ourTimerBlock, (void *) 2, 200LL, //timer group ticks &err); if (err) {printf("timerstart failed %d\n");} t3 = netapi_TimerGroupStartTimer( ourTimerBlock, (void *) 3, 300LL, //timer group ticks &err); if (err) {printf("timerstart failed %d\n");} #endif netcp_cfgReqStats(netapi_handle, our_stats_cb, 1,&err); if (err!=0) {printf("stats req failed\n");} /*********************************************/ /*****************end NETAPI STARTUP**********/ /*********************************************/ #if 0 /******************************************** * Basic pkt loopback test *********************************************/ printf("...runnining pure push/pop benchmark\n"); our_pktio_bench(100); #endif /**************unused stuff******************/ #if 0 /* create TRIE */ P_trie = trie_new(); if (!P_trie) {printf("trie alloc failed\n"); exit(1);} nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T)); if (!nat) {printf("malloc of nat table failed\n"); exit(1);} //gen_pkts(np2processorigBuffPtr - ((Cppi_HostDesc *) tempVA)->buffPtr); } tempVA = _Osal_qmssPhyToVirt(pHd[j-1]); sumf+= (int) ( ((Cppi_HostDesc *) tempVA)->origBuffPtr - ((Cppi_HostDesc *) tempVA)->buffPtr); t2=netapi_timing_stop(); sumt+= (t2-t1); //invalidate/wb for(j=0;j0;) { t1= netapi_timing_stop(); pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ)); if (!pHd[0]) continue; //got pkt for(i=1;(i VA tempVA = Osal_qmssPhyToVirt(pHd[i-1]); //try and preload desriptor __builtin_prefetch(tempVA); //netapi_pld(tempVA); //read next descriptor from queue pHd[i] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ)); #if 1 /* extract some meta data */ Cppi_getData (Cppi_DescType_HOST, (Cppi_Desc*)tempVA, &buf[jj], &len[jj]); pinfo = nwal_mGetProtoInfo(tempVA); l3_off[jj]= nwal_mGetL3OffBytes(pinfo); l4_off[jj]= nwal_mGetL4Offset(pinfo); if(nwal_mGetAppidFmPkt(tempVA,&appid[jj]) != nwal_TRUE) { printf("ERROR!!!! AppID not available in incoming packet \n"); } //#define VERIFY_SOP #ifdef VERIFY_SOP if (sump < 200) printf("..sop off=%d\n", (int) buf[jj]- (int) ((Cppi_HostDesc *) tempVA)->origBuffPtr) ; #endif #endif jj+=1; } //finish last pkt in burst if(pHd[i-1]) { //convert previous descriptor PA -> VA tempVA = Osal_qmssPhyToVirt(pHd[i-1]); /* extract some meta data */ #if 1 pinfo = nwal_mGetProtoInfo(tempVA); l3_off[jj]= nwal_mGetL3OffBytes(pinfo); l4_off[jj]= nwal_mGetL4Offset(pinfo); if(nwal_mGetAppidFmPkt(tempVA,&appid[jj]) != nwal_TRUE) { printf("ERROR!!!! AppID not available in incoming packet \n"); } #endif //get ptr (Physical address) and length of associate buffer Cppi_getData (Cppi_DescType_HOST, (Cppi_Desc*)tempVA, &buf[jj], &len[jj]); jj+=1; } t2= netapi_timing_stop(); j+=(pHd[i-1]? i: (i-1)) ; if (jj>(M-n)) jj=0; l+=1; //n batches ltot+=1; if(pHd[i-1]) { if (i>max_batch) max_batch= i; } else { if( (i-1) >max_batch) max_batch = i-1; } //cleanup //printf("cleanup %d\n",i); for(k=0;k 10000) { printf("pkts rx %d batches=%d appid=%x l3_off=%d l4_off=%d len=%d buf=0x%x rxcycle= %d pkts/batchx1000=%d maxbatch=%d cycles per rawpush = %d\n", j,ltot, appid[j%M], l3_off[j%M],l4_off[j%M], len[j%M],buf[j%M], sumt/sump, (sump*1000)/l, max_batch, sumf/sump); sumt=sump=sumf=0; l=0; } } //cleanup any remaining buffers for(;;) { pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ)); if(!pHd[0]) break; tempVA = Osal_qmssPhyToVirt(pHd[0]); freeQ=Qmss_getQueueHandle(Cppi_getReturnQueue (Cppi_DescType_HOST, (Cppi_Desc *)tempVA)); netapi_utilCacheWbInv(tempVA,128); PKTIO_QMSS_QUEUE_PUSH_DESC_SIZE_RAW (freeQ, (void *) pHd[0], 128); } } #ifdef EXPERIMENTAL static inline void send_it(Ti_Pkt *tip, int len, ROUTE_SEC_T * p_sec) { unsigned long st1; unsigned long st2; int err=0; PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0}; nwalTxPktInfo_t meta_tx2={0}; st1=netapi_timing_start(); if (len<60) { unsigned int templen; char * p_pkt; len=60; Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len); stats.tx_min+=1; } Pktlib_setPacketLen(tip,len); meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ); meta_tx2.startOffset = 0; meta_tx2.ipOffBytes = 14; meta_tx2.ploadLen = len ; if(p_sec) { meta_tx2.txFlag1 |= NWAL_TX_FLAG1_DO_IPSEC_CRYPTO ; meta2.sa_handle=p_sec->tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied meta_tx2.enetPort=0; meta_tx2.saOffBytes=14+20; meta_tx2.saPayloadLen=len-14-20; //don't include tag, mac and outer header stats.sec_tx+=1; } meta2.u.tx_meta=&meta_tx2; pktio_send(netcp_tx_chan,tip,&meta2,&err); stats.tx +=1; st2=netapi_timing_start(); stats.send_cycles += (unsigned long long) (st2-st1); } void recv_cb_router(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; Ti_Pkt * tip; unsigned int templen; char * p_pkt; HEAD_T temp_head; unsigned int appid; IP_HEAD_T th; ROUTE_SEC_T *sec_data=NULL; unsigned long t1; unsigned long t2; unsigned long ct1; unsigned long ct2; unsigned short ip_pl; int n_c_ops; t1=netapi_timing_start(); ct1 =Osal_cache_op_measure(&n_c_ops); for(i=0;iappId)&0xff000000; switch(appid) { case(NETAPI_NETCP_MATCH_IPSEC): case(NETAPI_NETCP_MATCH_IPSEC_POLICY): { int tailen=12+2; memcpy(&temp_head,&p_pkt[14],sizeof(HEAD_T)); if (!check_header(&temp_head,&meta[i])) { stats.n_bad+=1; Pktlib_freePacket(tip); continue; } tailen+=p_pkt[len-12-2]; //padding length (12)should come from sec_ptr p_pkt = &p_pkt[8+16+20]; //16= iv len, should come from sec_ptr len -= (8+16+20+tailen); //16= iv len should come from sec ptr //now check inner headder. memcpy(&th,&p_pkt[14],20); if (!check_header(&temp_head,&meta[i])) { stats.n_bad+=1; Pktlib_freePacket(tip); continue; } Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len); Pktlib_setPacketLen(tip,len); if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data)<0) { stats.n_bad+=1; Pktlib_freePacket(tip); } else { send_it(tip,len,sec_data); } break; } case(NETAPI_NETCP_MATCH_GENERIC_MAC): if((p_pkt[12]!=0x8)||(p_pkt[13]!=0x00)) { stats.n_new+=1; Pktlib_freePacket(tip); continue; } if (!check_header(&temp_head,&meta[i])) { stats.n_bad+=1; Pktlib_freePacket(tip); continue; } memcpy(&th,&p_pkt[14],20); ip_pl= (((unsigned char *)&th.w1)[2]<<8) | ((unsigned char *)&th.w1)[3]; if ((ip_pl+14)<60) { len-= (60-(ip_pl+14)); stats.rx_min+=1; } Pktlib_setPacketLen(tip,len); if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data)<0) { stats.n_bad+=1; Pktlib_freePacket(tip); } else { send_it(tip,len,sec_data); } break; case(NETAPI_NETCP_MATCH_GENERIC_IP): Pktlib_freePacket(tip); stats.n_new=1; break; default: stats.n_new+=1; Pktlib_freePacket(tip); break; } } t2=netapi_timing_start(); ct2 =Osal_cache_op_measure(&n_c_ops); stats.app_cycles += (unsigned long long) (t2-t1); stats.tx_cache_cycles += (unsigned long long) (ct2-ct1); return; } #endif