From b76147919f9081fb4169ebd2de4925a0ab580210 Mon Sep 17 00:00:00 2001 From: David Lide Date: Mon, 6 Feb 2012 10:23:34 -0500 Subject: [PATCH] added del_ip, del_mac functions --- ti/runtime/netapi/netcp_cfg.h | 489 ++++---- ti/runtime/netapi/src/netcp_cfg.c | 1241 ++++++++++++--------- ti/runtime/netapi/test/net_test.c | 1729 +++++++++++++++-------------- 3 files changed, 1824 insertions(+), 1635 deletions(-) diff --git a/ti/runtime/netapi/netcp_cfg.h b/ti/runtime/netapi/netcp_cfg.h index 780768a..d4be186 100644 --- a/ti/runtime/netapi/netcp_cfg.h +++ b/ti/runtime/netapi/netcp_cfg.h @@ -1,243 +1,246 @@ -/*************************************************** - * File: netcp_cfg.h - * Purpose: netcp config API - ************************************************************** - *@file netcp_cfg.h - * - * @brief DESCRIPTION: netapi NETCP configuration API header file - * for user space transport library - * - * 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. - - ***************************************************/ - -#ifndef __NETCP_CFG__H -#define __NETCP_CFG__H - -#include "netapi.h" -#include "ti/drv/pa/pa.h" -#include "ti/runtime/pktlib/pktlib.h" - -//NETCP FLOW -typedef struct NETCP_CFG_FLOW_Tag -{ - int flowid; -} NETCP_CFG_FLOW_T; -typedef void * NETCP_CFG_FLOW_HANDLE_T; - - -//NETCP ROUTE -typedef struct NETCP_CFG_ROUTE_Tag -{ - NETCP_CFG_FLOW_HANDLE_T p_flow; - PKTIO_HANDLE_T * p_dest_q; - int nextAction; -} NETCP_CFG_ROUTE_T; -typedef void * NETCP_CFG_ROUTE_HANDLE_T; - -/*--------------flow management--------*/ -NETCP_CFG_FLOW_HANDLE_T netcp_cfgAddFlow(NETAPI_T , - int n, - Pktlib_HeapHandle handles[], - int * err ); -void netcp_cfgDelFlow(NETAPI_T , NETCP_CFG_FLOW_HANDLE_T , int * err); - -/*------------Routes------------------*/ -NETCP_CFG_ROUTE_HANDLE_T netcp_cfgAddRoute(NETAPI_T ,int nh, - Pktlib_HeapHandle heaps[], - int *err ); -void netcp_cfgDelRoute(NETAPI_T , NETCP_CFG_ROUTE_HANDLE_T, int *err ); - -/*-----------Actions----------*/ -#define NETCP_CFG_ACTION_DISCARD 0 -#define NETCP_CFG_ACTION_CONTINUE 1 //pass packet on to next classifier -#define NETCP_CFG_ACTION_TO_SW 2 - -/******************************************************************/ -/***********************APP ids for rx meta data********************/ -/******************************************************************/ -// NWAL "AP ids" for PA Rules that are added -#define NETAPI_NETCP_MATCH_GENERIC_MAC 0x10000000 //lower byte==interface -#define NETAPI_NETCP_MATCH_GENERIC_IP 0x20000000 //lower byte==interface -#define NETAPI_NETCP_MATCH_CLASS 0x80000000 //or' in classifier #, lower byte==interface - - -/*---------MAC APPID------------------*/ -typedef uint32_t NETCP_CFG_MACIF_T; - -/*------------L2----------------------*/ -typedef void * NETCP_CFG_VLAN_T; - -/*---------------IP APPID-------------------*/ -typedef uint32_t NETCP_CFG_IP_T; - -/* del mac i/f */ -void netcp_cfgDelMac(NETAPI_T h,int iface_no, int *err); -void netcp_cfgDelIp(NETAPI_T h, int iface_no, nwal_IpType ipType, - nwalIpAddr_t * ip_addr, - nwalIpOpt_t * ip_qualifiers, int *err); - - -/***************************************************************** - * Create a MAC interface - ****************************************************************/ -/* -* @brief API Creates a MAC interface - * - * @details This api is used to create a MAC interface. - * Once it is created, the MAC interface can be used to receive packets. The API - * adds a rule to the NETCP 1st level lookup tables to route all packets with destination - * MAC matching supplied argument and not matching any other lookup entry (see @ref netcp_cfgAddIp) to - * the supplied route, @ref NETCP_CFG_ROUTE_T, (or default route). - * Packets arriving that match this rule are identified in meta data with Appid= NETAPI_NETCP_MATCH_GENERIC_MAC - * Note: The internal SOC switch must be "taught" that this mac - * address is present by transmitting a packet with destination mac = this interface mac address. - * @param[in] @ref NETAPI_T: NETAPI instance - * @param[in] char *: pointer to 6 byte MAC address for interface - * @param[in] int : interface number (0,1,..) - * @param[in] int : switch port (0 don't care, 1 switch port 1, 1 switch port 2) [only 0 supported] - * @param[in] @ref NETCP_CFG_ROUTE_HANDLE_T : [future] handle of a created route or NULL to use internal default route - * @oaram[in] @ref NETCP_CFG_VLAN_T : [future[ vlan configuration . Set to NULL - * @param[in] int : [future] interface state (0=down, 1= up) - * @param[out] int * err: pointer to error return - * @retval @ref NETCP_CFG_MACIF_T : returned AppID for interface (this is returned in meta data for - * received packets matching this rule an no others) - * @pre @ref netapi_init - */ -NETCP_CFG_MACIF_T netcp_cfgCreateMacInterface( - NETAPI_T h, // - uint8_t *p_mac, //mac address associated with interface - int iface_no, //0,1, .. - int switch_port,//0=don't care, 1=switch port 1, 2=switch port 2 , .. - NETCP_CFG_ROUTE_HANDLE_T route, //NULL to use default - NETCP_CFG_VLAN_T vlan, //future - int state, //0=down, 1=up //FUTURE - int * err - ); - -/***************************************************************** - * Add IP address/qualifier to MAC interface - ****************************************************************/ -/* -* @brief API attaches an IP adderess and qualifier to a MAC interface - * - * @details This api is used to add an IP address to a MAC interface along - * with optional IP qualifier. A route, @ref NETCP_CFG_ROUTE_HANDLE_T,or NULL for default - * may be specified to indicate where to send packets matching the MAC interface MAC address, the - * supplied IP address and any qualifier. This API adds a rule to the NETCP level 1 lookup tables - * Packets arriving that match this rule are identified in meta data with Appid= NETAPI_NETCP_MATCH_GENERIC_IP - * Note: An IP address must be attached to enable NETCP Recevie Checksum offload feature - * @param[in] @ref NETAPI_T: NETAPI instance - * @param[in] int : interface number (0,1,..) - * @param[in] @ref nwal_IpType : type of IP address (V4 for V6) - * @oaram[in] @ref nwalIpAddr_t : ip_address - * @param[in] @ref nwalIpOpt_t : ip_qualifiers (all 0 for no qualifiers). This can be used to apply special handling for - * diffserv category for example - * @param[in] @ref NETCP_CFG_ROUTE_HANDLE_T : [future] handle of a created route or NULL to use internal default route - * @param[out] int * err: pointer to error return - * @retval @ref NETCP_CFG_IP_T : returned AppID for attached rule. This is returned in RX meta data for - * packets matching this rule and no other. - * @pre @ref netapi_init , @ref netcp_cfgAddMac - */ -NETCP_CFG_IP_T netcp_AddIp( - NETAPI_T h, - int iface_no, - nwal_IpType ipType, - nwalIpAddr_t * ip_addr, - nwalIpOpt_t * ip_qualifiers, - NETCP_CFG_ROUTE_HANDLE_T route, //NULL for default - int * err - ); - -/*------------------classification [FUTURE]-------------------*/ -typedef void *NETCP_CFG_CLASS_T; - -//add classifier -typedef struct NETCP_CFG_CLASSIFIER_Tag -{ - //tbd a classisfier - -} NETCP_CFG_CLASSIFIER_T; - -NETCP_CFG_CLASS_T netcp_cfgAddClass(NETAPI_T h, - NETCP_CFG_CLASSIFIER_T *p_class, - NETCP_CFG_ROUTE_HANDLE_T p_route, - int action, int * err); -//del classifier -void netcp_cfgDelClass(NETAPI_T h, - NETCP_CFG_CLASS_T p_class, - int *err); - - - -/*************************************************************************** -********************************STATS************************************** -**************************************************************************/ - -/* - * @brief This is the callback function that is used to return statistics from NETCP - * - * @details The application provides a callback function that NETAPI uses to report statistics. -* The request for stats is generated from the @ref netcp_cfgReqStats API. - * Note: to receive ths stats callback, the @ref netapi_netcpPoll funcition must be called - * @param[in] @ref NETAPI_T: NETAPI instance - * @param[in] @ref paSysStats_t * : the PA (NETCP packet accelerator subsystem) statistics block - * @retval none - * @pre @ref netapi_init , @ref netapi_cfgReqStats, @ref netapi_netcpPoll - */ -//stats CB -typedef void (*NETCP_CFG_STATS_CB)( NETAPI_T h, paSysStats_t* pPaStats); - - -//stats request -/* - * @brief API request statistics from NETCP - * - * @details This api is used to request a statistics from NETCP. This will generate a stats request - * command to NETCP. Sometime later, the statistics result will arrive and will be passed to - * the caller via the asynchronus callback @ref NETCP_CFG_STATS_CB that is registered in this call. - * Note: to receive the stats callback, the @ref netapi_netcpPoll funcition must be called - * @param[in] @ref NETAPI_T: NETAPI instance - * @param[in] @ref NETCP_CFG_STATS_CB : the function to call with the resulting statistics block - * @param[in] int : clear the stats in NETCP after the report (0=no, 1=yes) - * @param[out] int * err: pointer to error return - * @retval none - * @pre @ref netapi_init - */ -void netcp_cfgReqStats(NETAPI_T h, //NEAPI instance - NETCP_CFG_STATS_CB c, //stats report callback function - int doClear, //0: don't clear, 1 clear - int *err); - -#endif - +/*************************************************** + * File: netcp_cfg.h + * Purpose: netcp config API + ************************************************************** + *@file netcp_cfg.h + * + * @brief DESCRIPTION: netapi NETCP configuration API header file + * for user space transport library + * + * 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. + + ***************************************************/ + +#ifndef __NETCP_CFG__H +#define __NETCP_CFG__H + +#include "netapi.h" +#include "ti/drv/pa/pa.h" +#include "ti/runtime/pktlib/pktlib.h" + +//NETCP FLOW +typedef struct NETCP_CFG_FLOW_Tag +{ + int flowid; +} NETCP_CFG_FLOW_T; +typedef void * NETCP_CFG_FLOW_HANDLE_T; + + +//NETCP ROUTE +typedef struct NETCP_CFG_ROUTE_Tag +{ + NETCP_CFG_FLOW_HANDLE_T p_flow; + PKTIO_HANDLE_T * p_dest_q; + int nextAction; +} NETCP_CFG_ROUTE_T; +typedef void * NETCP_CFG_ROUTE_HANDLE_T; + +/*--------------flow management--------*/ +NETCP_CFG_FLOW_HANDLE_T netcp_cfgAddFlow(NETAPI_T , + int n, + Pktlib_HeapHandle handles[], + int * err ); +void netcp_cfgDelFlow(NETAPI_T , NETCP_CFG_FLOW_HANDLE_T , int * err); + +/*------------Routes------------------*/ +NETCP_CFG_ROUTE_HANDLE_T netcp_cfgAddRoute(NETAPI_T ,int nh, + Pktlib_HeapHandle heaps[], + int *err ); +void netcp_cfgDelRoute(NETAPI_T , NETCP_CFG_ROUTE_HANDLE_T, int *err ); + +/*-----------Actions----------*/ +#define NETCP_CFG_ACTION_DISCARD 0 +#define NETCP_CFG_ACTION_CONTINUE 1 //pass packet on to next classifier +#define NETCP_CFG_ACTION_TO_SW 2 + +/******************************************************************/ +/***********************APP ids for rx meta data********************/ +/******************************************************************/ +// NWAL "AP ids" for PA Rules that are added +#define NETAPI_NETCP_MATCH_GENERIC_MAC 0x10000000 //lower byte==interface +#define NETAPI_NETCP_MATCH_GENERIC_IP 0x20000000 //lower byte==interface +#define NETAPI_NETCP_MATCH_CLASS 0x80000000 //or' in classifier #, lower byte==interface + + +/*---------MAC APPID------------------*/ +typedef uint32_t NETCP_CFG_MACIF_T; + +/*------------L2----------------------*/ +typedef void * NETCP_CFG_VLAN_T; + +/*---------------IP APPID-------------------*/ +typedef uint32_t NETCP_CFG_IP_T; + +/* del mac i/f */ +void netcp_cfgDelMac(NETAPI_T h,int iface_no, int *err); +void netcp_cfgDelIp(NETAPI_T h, int iface_no, nwal_IpType ipType, + nwalIpAddr_t * ip_addr, + nwalIpOpt_t * ip_qualifiers, + NETCP_CFG_IP_T, + int *err); + + +/***************************************************************** + * Create a MAC interface + ****************************************************************/ +/* +* @brief API Creates a MAC interface + * + * @details This api is used to create a MAC interface. + * Once it is created, the MAC interface can be used to receive packets. The API + * adds a rule to the NETCP 1st level lookup tables to route all packets with destination + * MAC matching supplied argument and not matching any other lookup entry (see @ref netcp_cfgAddIp) to + * the supplied route, @ref NETCP_CFG_ROUTE_T, (or default route). + * Packets arriving that match this rule are identified in meta data with Appid= NETAPI_NETCP_MATCH_GENERIC_MAC + * Note: The internal SOC switch must be "taught" that this mac + * address is present by transmitting a packet with destination mac = this interface mac address. + * @param[in] @ref NETAPI_T: NETAPI instance + * @param[in] char *: pointer to 6 byte MAC address for interface + * @param[in] int : interface number (0,1,..) + * @param[in] int : switch port (0 don't care, 1 switch port 1, 1 switch port 2) [only 0 supported] + * @param[in] @ref NETCP_CFG_ROUTE_HANDLE_T : [future] handle of a created route or NULL to use internal default route + * @oaram[in] @ref NETCP_CFG_VLAN_T : [future[ vlan configuration . Set to NULL + * @param[in] int : [future] interface state (0=down, 1= up) + * @param[out] int * err: pointer to error return + * @retval @ref NETCP_CFG_MACIF_T : returned AppID for interface (this is returned in meta data for + * received packets matching this rule an no others) + * @pre @ref netapi_init + */ +NETCP_CFG_MACIF_T netcp_cfgCreateMacInterface( + NETAPI_T h, // + uint8_t *p_mac, //mac address associated with interface + int iface_no, //0,1, .. + int switch_port,//0=don't care, 1=switch port 1, 2=switch port 2 , .. + NETCP_CFG_ROUTE_HANDLE_T route, //NULL to use default + NETCP_CFG_VLAN_T vlan, //future + int state, //0=down, 1=up //FUTURE + int * err + ); + +/***************************************************************** + * Add IP address/qualifier to MAC interface + ****************************************************************/ +/* +* @brief API attaches an IP adderess and qualifier to a MAC interface + * + * @details This api is used to add an IP address to a MAC interface along + * with optional IP qualifier. A route, @ref NETCP_CFG_ROUTE_HANDLE_T,or NULL for default + * may be specified to indicate where to send packets matching the MAC interface MAC address, the + * supplied IP address and any qualifier. This API adds a rule to the NETCP level 1 lookup tables + * Packets arriving that match this rule are identified in meta data with Appid= NETAPI_NETCP_MATCH_GENERIC_IP + * Note: An IP address must be attached to enable NETCP Recevie Checksum offload feature + * @param[in] @ref NETAPI_T: NETAPI instance + * @param[in] int : interface number (0,1,..) + * @param[in] @ref nwal_IpType : type of IP address (V4 for V6) + * @oaram[in] @ref nwalIpAddr_t : ip_address + * @param[in] @ref nwalIpOpt_t : ip_qualifiers (all 0 for no qualifiers). This can be used to apply special handling for + * diffserv category for example + * @param[in] @ref NETCP_CFG_ROUTE_HANDLE_T : [future] handle of a created route or NULL to use internal default route + * @param[out] int * err: pointer to error return + * @retval @ref NETCP_CFG_IP_T : returned AppID for attached rule. This is returned in RX meta data for + * packets matching this rule and no other. + * @pre @ref netapi_init , @ref netcp_cfgAddMac + */ +NETCP_CFG_IP_T netcp_cfgAddIp( + NETAPI_T h, + int iface_no, + nwal_IpType ipType, + nwalIpAddr_t * ip_addr, + nwalIpOpt_t * ip_qualifiers, + NETCP_CFG_ROUTE_HANDLE_T route, //NULL for default + int * err + ); +#define netcp_addIp netcp_cfgAddIp //oops + +/*------------------classification [FUTURE]-------------------*/ +typedef void *NETCP_CFG_CLASS_T; + +//add classifier +typedef struct NETCP_CFG_CLASSIFIER_Tag +{ + //tbd a classisfier + +} NETCP_CFG_CLASSIFIER_T; + +NETCP_CFG_CLASS_T netcp_cfgAddClass(NETAPI_T h, + NETCP_CFG_CLASSIFIER_T *p_class, + NETCP_CFG_ROUTE_HANDLE_T p_route, + int action, int * err); +//del classifier +void netcp_cfgDelClass(NETAPI_T h, + NETCP_CFG_CLASS_T p_class, + int *err); + + + +/*************************************************************************** +********************************STATS************************************** +**************************************************************************/ + +/* + * @brief This is the callback function that is used to return statistics from NETCP + * + * @details The application provides a callback function that NETAPI uses to report statistics. +* The request for stats is generated from the @ref netcp_cfgReqStats API. + * Note: to receive ths stats callback, the @ref netapi_netcpPoll funcition must be called + * @param[in] @ref NETAPI_T: NETAPI instance + * @param[in] @ref paSysStats_t * : the PA (NETCP packet accelerator subsystem) statistics block + * @retval none + * @pre @ref netapi_init , @ref netapi_cfgReqStats, @ref netapi_netcpPoll + */ +//stats CB +typedef void (*NETCP_CFG_STATS_CB)( NETAPI_T h, paSysStats_t* pPaStats); + + +//stats request +/* + * @brief API request statistics from NETCP + * + * @details This api is used to request a statistics from NETCP. This will generate a stats request + * command to NETCP. Sometime later, the statistics result will arrive and will be passed to + * the caller via the asynchronus callback @ref NETCP_CFG_STATS_CB that is registered in this call. + * Note: to receive the stats callback, the @ref netapi_netcpPoll funcition must be called + * @param[in] @ref NETAPI_T: NETAPI instance + * @param[in] @ref NETCP_CFG_STATS_CB : the function to call with the resulting statistics block + * @param[in] int : clear the stats in NETCP after the report (0=no, 1=yes) + * @param[out] int * err: pointer to error return + * @retval none + * @pre @ref netapi_init + */ +void netcp_cfgReqStats(NETAPI_T h, //NEAPI instance + NETCP_CFG_STATS_CB c, //stats report callback function + int doClear, //0: don't clear, 1 clear + int *err); + +#endif + diff --git a/ti/runtime/netapi/src/netcp_cfg.c b/ti/runtime/netapi/src/netcp_cfg.c index eb971fa..abc5ebb 100644 --- a/ti/runtime/netapi/src/netcp_cfg.c +++ b/ti/runtime/netapi/src/netcp_cfg.c @@ -1,531 +1,710 @@ -/********************************************************** - * file: netcp_cfg.c - * purpose: netcp configurations routines - ************************************************************** - * FILE: netcp_cfg.c - * - * DESCRIPTION: netcp configuration main source file for user space transport - * library - * - * 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 "netapi.h" -#include "netcp_cfg.h" -#include "netapi_loc.h" - -/****************************************************************** - ********************Utility************************************* -*******************************************************************/ - - -//get a free transaction id -static NetapiNwalTransInfo_t * netapi_GetFreeTransInfo(NETAPI_GLOBAL_T *p_global, nwal_TransID_t *pTransId) -{ - uint16_t count=0; - - count=0; - while(count < TUNE_NETAPI_MAX_NUM_TRANS) - { - if((p_global->nwal_context.transInfos[count].inUse) != nwal_TRUE) - { - p_global->nwal_context.transInfos[count].inUse = nwal_TRUE; - *pTransId = count; - return(&p_global->nwal_context.transInfos[count]); - } - count++; - } - - /* trouble. need to wait for one to free up*/ - /* to do: handle this by forcing a poll of cntrl queue*/ - printf(">netcp_cfg: trying to get free transaction slot but all full!!\n"); - return NULL; - -} -//internal: insert an IP address into iface -void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, - nwal_IpType ipType, - nwalIpAddr_t *ip_addr, - nwalIpOpt_t *ip_qualifiers, - int iface_no, - void * handle) -{ -int i; -for(i=0;iinterfaces[iface_no].ips[i].in_use) - { - p->interfaces[iface_no].ips[i].in_use=1; - memcpy(&p->interfaces[iface_no].ips[i].ip_addr, ip_addr, sizeof(nwalIpAddr_t)); - if(ip_qualifiers) - memcpy(&p->interfaces[iface_no].ips[i].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t)); - else - memset(&p->interfaces[iface_no].ips[i].ip_qualifiers, 0, sizeof(nwalIpOpt_t)); - p->interfaces[iface_no].ips[i].ip_type = ipType; - p->interfaces[iface_no].ips[i].nwal_handle = handle; - return; - } -} -printf(">netcp_cfg - add ip: no room in table\n"); - -} - - -//internal: instert interface info into global context -void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac, - int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle) -{ - if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES)) - { - memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T)); - p->interfaces[iface_no].in_use = 1; - memcpy(&p->interfaces[iface_no].mac[0], p_mac,6); - p->interfaces[iface_no].state = state; - //todo p->interfaces[iface_no].vlan = vlan; - p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule - } - else printf(">netcp_cfg insert interface # out of range %d\n",iface_no); - -} -//internal: clear inteface entry -void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no) -{ - if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES)) - { - p->interfaces[iface_no].in_use = 0; - } - else printf(">netcp_cfg delete interface # out of range %d\n",iface_no); - -} - - -//internal: - -/***********************************************************************************/ -/****************************************API****************************************/ -/***********************************************************************************/ - - -/***************************************************************** - * Queury Stats - ****************************************************************/ -void netcp_cfgReqStats(NETAPI_T h, NETCP_CFG_STATS_CB cb, int doClear, int *err) -{ -nwal_RetValue ret; -NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h; -NetapiNwalTransInfo_t *pTransInfo; -nwal_TransID_t transId; -if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;} -*err =0; - -pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId); -if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;} -pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST; -pTransInfo->netapi_handle = h; -n->nwal_local.stats_cb = cb; -ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle, - transId, - NULL, - doClear); -if(ret != nwal_OK) -{ - pTransInfo->inUse = nwal_FALSE; - *err = NETAPI_ERR_BUSY; //no resources?? - printf("> netcp_cfg reqStats failed, err=%d\n",ret); -} - -} -/***************************************************************** - * CREATE A MAC INTERFACE - ****************************************************************/ -NETCP_CFG_MACIF_T netcp_cfgCreateMacInterface( - NETAPI_T h, - uint8_t *p_mac, - int iface_no, - int switch_port, - NETCP_CFG_ROUTE_HANDLE_T route, - NETCP_CFG_VLAN_T vlan, //future - int state, //0=down, 1=up //ignored - int * err - ) -{ -NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h; -nwalMacParam_t MacInfo= { - 0, /* validParams */ - 0, /* ifNum */ - 0, /* vlanId */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Local mac */ - NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */ - NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */ - CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */ - QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */ -}; - -nwal_RetValue retValue; -NetapiNwalTransInfo_t *pTransInfo; -nwal_TransID_t trans_id; - - if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;} - *err =0; - - pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id); - if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return -1;} - pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC; - pTransInfo->netapi_handle = h; - - /* set up MacInfo */ - memcpy(&MacInfo.macAddr,p_mac,6); - /* todo: vlan */ - MacInfo.ifNum = switch_port; /* todo: check for 0/1 relative*/ - -#if 0 //todo - if (route != NULL) - { - MacInfo.appRxPktFlowId = ((NETCP_CFG_FLOW_T *)(route.flow))->flowid; - MacInfo.appRxPktQueue = PKTIO_GET_Q(route->p_dest_q); - //handle action ?? - } -#endif - pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING; - retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, - trans_id, - (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no), - &MacInfo, - &pTransInfo->handle); - if(retValue != nwal_OK) - { - *err = NETAPI_ERR_NWAL_ERR0; - printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n", - retValue); - pTransInfo->inUse = nwal_FALSE; - return -1; - } - //pTransInfo->inUse = nwal_FALSE; - - //wait here until its done since scheduler isn't running yet most likely.. - // todo: make this handled by scheduler poll later ?? - if(trans_id != NWAL_TRANSID_SPIN_WAIT) - { - n->nwal_local.numPendingCfg++; - while ((volatile) n->nwal_local.numPendingCfg) - { - // if response is there, then this poll squirts out in the CTl poll callback, - // which handles the rest (including decrmenting #pending!! - nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL); - } - } - printf (">netcp cfg: MAC i/f added\n"); - netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, - p_mac, iface_no, state,vlan, - (void *) pTransInfo->handle); - pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE; - pTransInfo->inUse = nwal_FALSE; - return (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no); -} - - -/*****************************************************************/ -/***************Delete a mac interface****************************/ -/*****************************************************************/ -void netcp_cfgDelMac(NETAPI_T h,int iface_no, int *err) -{ - - *err =0; - - netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context, iface_no); - printf(">netcp_cfg: del mac not fully implemented \n"); - return; -} - - -/*****************************************************************/ -/***************Add IP to MAC interface****************************/ -/*****************************************************************/ -NETCP_CFG_IP_T netcp_addIp( - NETAPI_T h, - int iface_no, - nwal_IpType ipType, - nwalIpAddr_t * ip_addr, - nwalIpOpt_t * ip_qualifiers, - NETCP_CFG_ROUTE_HANDLE_T route, //NULL for default - int * err - ) -{ -NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h; -void * n_handle; -nwalIpParam_t nwalIpParam= { - pa_IPV4, /* IP Type */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Dest IP */ - { 0x0,0,0,0},/* IP Options */ - NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */ - NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */ - CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */ - QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */ -}; -nwal_RetValue retValue; -NetapiNwalTransInfo_t *pTransInfo; -nwal_TransID_t trans_id; - - - //verify that iface has been configurred - if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return -1;} - - if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use) - { - n_handle = netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle; - } - else - { - *err = NETAPI_ERR_BAD_INPUT; - return -1; - } - - //get a transaction object for config action - pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id); - if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return -1;} - pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP; - pTransInfo->netapi_handle = h; - - //build nwalIpParam - memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t)); - nwalIpParam.ipType=ipType; - if(route) - { - //todo: support app defined routes - } - else{} //use nwal defaults - if (ip_qualifiers) - memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); - else - memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t)); - - //perform config action - pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING; - retValue = nwal_setIPAddr( netapi_get_global()->nwal_context.nwalInstHandle, - trans_id, - (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_IP | iface_no), - n_handle, - &nwalIpParam, - &pTransInfo->handle); - - if(retValue != nwal_OK) - { - *err = NETAPI_ERR_NWAL_ERR0; - printf (">netcp cfg: nwal_setIP returned Error Code %d\n", - retValue); - pTransInfo->inUse = nwal_FALSE; - return -1; - } - //wait here until its done since scheduler isn't running yet most likely.. - // todo: make this handled by scheduler poll later ?? - if(trans_id != NWAL_TRANSID_SPIN_WAIT) - { - n->nwal_local.numPendingCfg++; - while ((volatile) n->nwal_local.numPendingCfg) - { - // if response is there, then this poll squirts out in the CTl poll callback, - // which handles the rest (including decrmenting #pending!! - nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL); - } - } - printf (">netcp cfg: IP added\n"); - netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, - ip_addr, ip_qualifiers, iface_no, - pTransInfo->handle); - pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE; - pTransInfo->inUse = nwal_FALSE; - return (NETAPI_NETCP_MATCH_GENERIC_IP | iface_no); -} - - - -/*************************************************************************/ -/*********************************INTERNAL*******************************/ -/************************************************************************/ - -/*************************************************************** - ********************METCP CMD Reply Callback****************** - ***************************************************************/ -void netapi_NWALCmdCallBack (nwal_AppId appHandle, - uint16_t trans_id, - nwal_RetValue ret) -{ - NetapiNwalTransInfo_t * p_trans; - NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL; - - if(trans_id == NWAL_TRANSID_SPIN_WAIT) - { - netapi_get_global()->nwal_context.numBogusTransIds++; - return; - } - - p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id]; - p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local; - - if(ret != nwal_OK) - { - printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n", - ret); - //todo: atomic inc - netapi_get_global()->nwal_context.numCmdFail++; - } - else - { - //todo: atomic inc - netapi_get_global()->nwal_context.numCmdPass++; - switch(p_trans->transType) - { - case NETAPI_NWAL_HANDLE_TRANS_MAC: - { - if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING) - { - p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN; - } - else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING) - { - p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE; - } - break; - } - case NETAPI_NWAL_HANDLE_TRANS_IP: - { - if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING) - { - p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN; - } - else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING) - { - p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE; - } - break; - } -#if 0 - case TEST_NWAL_HANDLE_TRANS_PORT: - { - if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING) - { - testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN; - } - else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING) - { - testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE; - } - break; - } - case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC: - { - if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING) - { - testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN; - } - else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING) - { - System_printf ("Set Security Assoc Close ACK received for trans_id: %d\n", - testNwLocContext.transInfos[trans_id].transType,trans_id); - nwal_SystemFlush(); - testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE; - } - break; - } -case TEST_NWAL_HANDLE_TRANS_SEC_POLICY: - { - if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING) - { - testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN; - } - else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING) - { - System_printf ("Set Security Policy Close ACK received for trans_id: %d\n", - testNwLocContext.transInfos[trans_id].transType,trans_id); - nwal_SystemFlush(); - testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE; - } - break; - } -#endif - default: - { - printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n", - p_trans->transType,trans_id); - break; - } - } - } - - p_local->numPendingCfg--; - - if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE) - { - p_trans->inUse = nwal_FALSE; - } - -} - - -/*******************************************************/ -/**************stats reply callback**********************/ -/*******************************************************/ -void netapi_NWALCmdPaStatsReply (nwal_AppId appHandle, - nwal_TransID_t trans_id, - paSysStats_t *stats) -{ - NetapiNwalTransInfo_t * p_trans; - NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL; - - if(trans_id == NWAL_TRANSID_SPIN_WAIT) - { - netapi_get_global()->nwal_context.numBogusTransIds++; - return; - } - - p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id]; - p_trans->inUse = nwal_FALSE; - p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local; - - //save a local copy of some stuff*/ - p_local->numL2PktsRecvd=stats->classify1.nPackets; - p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets; -#if 0 - p_local->numL4PktsRecvd=stats->; - p_local->numL4PktsSent=stats->; - p_local->TxErrDrop=stats->; -#endif - //callout result to application !! - if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats); - -} - +/********************************************************** + * file: netcp_cfg.c + * purpose: netcp configurations routines + ************************************************************** + * FILE: netcp_cfg.c + * + * DESCRIPTION: netcp configuration main source file for user space transport + * library + * + * 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 "netapi.h" +#include "netcp_cfg.h" +#include "netapi_loc.h" + +/****************************************************************** + ********************Utility************************************* +*******************************************************************/ + + +//get a free transaction id +static NetapiNwalTransInfo_t * netapi_GetFreeTransInfo(NETAPI_GLOBAL_T *p_global, nwal_TransID_t *pTransId) +{ + uint16_t count=0; + + count=0; + while(count < TUNE_NETAPI_MAX_NUM_TRANS) + { + if((p_global->nwal_context.transInfos[count].inUse) != nwal_TRUE) + { + p_global->nwal_context.transInfos[count].inUse = nwal_TRUE; + *pTransId = count; + return(&p_global->nwal_context.transInfos[count]); + } + count++; + } + + /* trouble. need to wait for one to free up*/ + /* to do: handle this by forcing a poll of cntrl queue*/ + printf(">netcp_cfg: trying to get free transaction slot but all full!!\n"); + return NULL; + +} + +//internal: find a free slot for IP rule in interface +static int netcp_cfgp_find_ip_slot(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, + int iface_no) +{ + int i; + if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES)) + { + return -1; + } + if (!p->interfaces[iface_no].in_use) return -1; + + //find a free entry + for(i=0;iinterfaces[iface_no].ips[i].in_use) + { + p->interfaces[iface_no].ips[i].in_use = 2; //pending + return i; + } + } + return -1; +} + +//internal: insert an IP address into iface +static void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, + nwal_IpType ipType, + nwalIpAddr_t *ip_addr, + nwalIpOpt_t *ip_qualifiers, + int iface_no, + int ip_slot, //we 'reserved it already' + void * handle) +{ + p->interfaces[iface_no].ips[ip_slot].in_use=1; + memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_addr, ip_addr, sizeof(nwalIpAddr_t)); + if(ip_qualifiers) + memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t)); + else + memset(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, 0, sizeof(nwalIpOpt_t)); + p->interfaces[iface_no].ips[ip_slot].ip_type = ipType; + p->interfaces[iface_no].ips[ip_slot].nwal_handle = handle; + return; +} + + +//internal: instert interface info into global context +static void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac, + int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle) +{ + if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES)) + { + memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T)); + p->interfaces[iface_no].in_use = 1; + memcpy(&p->interfaces[iface_no].mac[0], p_mac,6); + p->interfaces[iface_no].state = state; + //todo p->interfaces[iface_no].vlan = vlan; + p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule + } + else printf(">netcp_cfg insert interface # out of range %d\n",iface_no); + +} +//internal: clear inteface entry +static void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no) +{ + if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES)) + { + p->interfaces[iface_no].in_use = 0; + } +} +//internal: free IP slot associated with ip address +static void netcp_cfgp_delete_ip( + NETAPI_NWAL_GLOBAL_CONTEXT_T *p, + int iface_no, + int ip_slot ) +{ + if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES)) + { + return ; + } + if (!p->interfaces[iface_no].in_use) return ; + if ((ip_slot <0)||(ip_slot>TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return ; + p->interfaces[iface_no].ips[ip_slot].in_use=0; + return; +} + + +//internal: get IP handle associated with ip address +static void *netcp_cfgp_get_ip_handle( + NETAPI_NWAL_GLOBAL_CONTEXT_T *p, + int iface_no, + int ip_slot ) +{ + if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES)) + { + return NULL; + } + if (!p->interfaces[iface_no].in_use) return NULL; + if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return NULL; + if (!p->interfaces[iface_no].ips[ip_slot].in_use) return NULL; + return (void *) p->interfaces[iface_no].ips[ip_slot].nwal_handle; +} + +//internal: get handle associated with interface +static void* netcp_cfgp_get_mac_handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no) +{ + if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES)) + { + return NULL; + } + else if ( p->interfaces[iface_no].in_use) + { + return (void *) p->interfaces[iface_no].nwal_handle; + } + //no valid entry in slot + return NULL; +} + + +/***********************************************************************************/ +/****************************************API****************************************/ +/***********************************************************************************/ + + +/***************************************************************** + * Queury Stats + ****************************************************************/ +void netcp_cfgReqStats(NETAPI_T h, NETCP_CFG_STATS_CB cb, int doClear, int *err) +{ +nwal_RetValue ret; +NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h; +NetapiNwalTransInfo_t *pTransInfo; +nwal_TransID_t transId; +if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;} +*err =0; + +pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId); +if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;} +pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST; +pTransInfo->netapi_handle = h; +n->nwal_local.stats_cb = cb; +ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle, + transId, + NULL, + doClear); +if(ret != nwal_OK) +{ + pTransInfo->inUse = nwal_FALSE; + *err = NETAPI_ERR_BUSY; //no resources?? + printf("> netcp_cfg reqStats failed, err=%d\n",ret); +} + +} +/***************************************************************** + * CREATE A MAC INTERFACE + ****************************************************************/ +NETCP_CFG_MACIF_T netcp_cfgCreateMacInterface( + NETAPI_T h, + uint8_t *p_mac, + int iface_no, + int switch_port, + NETCP_CFG_ROUTE_HANDLE_T route, + NETCP_CFG_VLAN_T vlan, //future + int state, //0=down, 1=up //ignored + int * err + ) +{ +NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h; +nwalMacParam_t MacInfo= { + 0, /* validParams */ + 0, /* ifNum */ + 0, /* vlanId */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Local mac */ + NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */ + NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */ + CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */ + QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */ +}; + +nwal_RetValue retValue; +NetapiNwalTransInfo_t *pTransInfo; +nwal_TransID_t trans_id; + + if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;} + *err =0; + + pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id); + if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return -1;} + pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC; + pTransInfo->netapi_handle = h; + + /* set up MacInfo */ + memcpy(&MacInfo.macAddr,p_mac,6); + /* todo: vlan */ + MacInfo.ifNum = switch_port; /* todo: check for 0/1 relative*/ + +#if 0 //todo + if (route != NULL) + { + MacInfo.appRxPktFlowId = ((NETCP_CFG_FLOW_T *)(route.flow))->flowid; + MacInfo.appRxPktQueue = PKTIO_GET_Q(route->p_dest_q); + //handle action ?? + } +#endif + pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING; + retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, + trans_id, + (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no), + &MacInfo, + &pTransInfo->handle); + if(retValue != nwal_OK) + { + *err = NETAPI_ERR_NWAL_ERR0; + printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n", + retValue); + pTransInfo->inUse = nwal_FALSE; + return -1; + } + //pTransInfo->inUse = nwal_FALSE; + + //wait here until its done since scheduler isn't running yet most likely.. + // todo: make this handled by scheduler poll later ?? + if(trans_id != NWAL_TRANSID_SPIN_WAIT) + { + n->nwal_local.numPendingCfg++; + while ((volatile) n->nwal_local.numPendingCfg) + { + // if response is there, then this poll squirts out in the CTl poll callback, + // which handles the rest (including decrmenting #pending!! + nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL); + } + } + printf (">netcp cfg: MAC i/f %d added\n", iface_no); + netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, + p_mac, iface_no, state,vlan, + (void *) pTransInfo->handle); + pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE; + pTransInfo->inUse = nwal_FALSE; + return (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no); +} + + +/*****************************************************************/ +/***************Delete a mac interface****************************/ +/*****************************************************************/ +void netcp_cfgDelMac(NETAPI_T h,int iface_no, int *err) +{ + nwal_RetValue ret; + NetapiNwalTransInfo_t *pTransInfo; + nwal_TransID_t trans_id; + NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h; + void * ifHandle; + + //get the nwal handle assoicated with this iface + ifHandle = netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no ); + if(!ifHandle) + {*err = NETAPI_ERR_BAD_INPUT; return ;} + *err =0; + + //get a transaction id + pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id); + if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;} + pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC; + pTransInfo->netapi_handle = h; + //issue request + ret = nwal_delMacIface( + ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, + trans_id, + ifHandle); + if(ret != nwal_OK) + { + *err = NETAPI_ERR_NWAL_ERR0; + printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n", + ret); + pTransInfo->inUse = nwal_FALSE; + return ; + } + //wait here until its done since scheduler isn't running yet most likely.. + // todo: make this handled by scheduler poll later ?? + if(trans_id != NWAL_TRANSID_SPIN_WAIT) + { + n->nwal_local.numPendingCfg++; + while ((volatile) n->nwal_local.numPendingCfg) + { + // if response is there, then this poll squirts out in the CTl poll callback, + // which handles the rest (including decrmenting #pending!! + nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL); + } + } + printf (">netcp cfg: MAC i/f %d deleted\n",iface_no); + pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE; + pTransInfo->inUse = nwal_FALSE; + //zap the entry + netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context, iface_no); + return ; +} + + +/*****************************************************************/ +/***************Add IP to MAC interface****************************/ +/*****************************************************************/ +NETCP_CFG_IP_T netcp_cfgAddIp( + NETAPI_T h, + int iface_no, + nwal_IpType ipType, + nwalIpAddr_t * ip_addr, + nwalIpOpt_t * ip_qualifiers, + NETCP_CFG_ROUTE_HANDLE_T route, //NULL for default + int * err + ) +{ +NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h; +void * n_handle; +nwalIpParam_t nwalIpParam= { + pa_IPV4, /* IP Type */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Dest IP */ + { 0x0,0,0,0},/* IP Options */ + NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */ + NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */ + CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */ + QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */ +}; +nwal_RetValue retValue; +NetapiNwalTransInfo_t *pTransInfo; +nwal_TransID_t trans_id; +int ip_slot=-1; +NETCP_CFG_IP_T ip_rule_id; + + //verify that iface has been configurred + if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return -1;} + + if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use) + { + n_handle = netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle; + } + else + { + *err = NETAPI_ERR_BAD_INPUT; + return -1; + } + //find free slot for IP & reserve + ip_slot= netcp_cfgp_find_ip_slot(&netapi_get_global()->nwal_context, + iface_no); + if (ip_slot <0) + { + *err= NETAPI_ERR_NOMEM; //no room + } + + //get a transaction object for config action + pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id); + if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return -1;} + pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP; + pTransInfo->netapi_handle = h; + + //build nwalIpParam + memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t)); + nwalIpParam.ipType=ipType; + if(route) + { + //todo: support app defined routes + } + else{} //use nwal defaults + if (ip_qualifiers) + memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); + else + memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t)); + + //build the rule id that will be returned when a packet matches + ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&&0xff)<<8); + //perform config action + pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING; + retValue = nwal_setIPAddr( netapi_get_global()->nwal_context.nwalInstHandle, + trans_id, + (nwal_AppId) (ip_rule_id), + n_handle, + &nwalIpParam, + &pTransInfo->handle); + + if(retValue != nwal_OK) + { + *err = NETAPI_ERR_NWAL_ERR0; + printf (">netcp cfg: nwal_setIP returned Error Code %d\n", + retValue); + pTransInfo->inUse = nwal_FALSE; + //zap the entry + netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context, + iface_no, + ip_slot); + + return -1; + } + //wait here until its done since scheduler isn't running yet most likely.. + // todo: make this handled by scheduler poll later ?? + if(trans_id != NWAL_TRANSID_SPIN_WAIT) + { + n->nwal_local.numPendingCfg++; + while ((volatile) n->nwal_local.numPendingCfg) + { + // if response is there, then this poll squirts out in the CTl poll callback, + // which handles the rest (including decrmenting #pending!! + nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL); + } + } + printf (">netcp cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot); + netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, + ip_addr, ip_qualifiers, iface_no, ip_slot, + pTransInfo->handle); + pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE; + pTransInfo->inUse = nwal_FALSE; + return (ip_rule_id); +} + +/*****************************************************************/ +/***************Delete an attached IP*****************************/ +/*****************************************************************/ +void netcp_cfgDelIp(NETAPI_T h, int iface_no, nwal_IpType ipType, + nwalIpAddr_t * ip_addr, + nwalIpOpt_t * ip_qualifiers, + NETCP_CFG_IP_T ip_rule_id, + int *err) +{ + nwal_RetValue ret; + NetapiNwalTransInfo_t *pTransInfo; + nwal_TransID_t trans_id; + NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h; + void * ifHandle; + int ip_slot = (ip_rule_id>>8)&0xff; + + //get the nwal handle assoicated with this ip + ifHandle = netcp_cfgp_get_ip_handle( + &netapi_get_global()->nwal_context, iface_no, + ip_slot ); + if(!ifHandle) + {*err = NETAPI_ERR_BAD_INPUT; return ;} + *err =0; + + //get a transaction id + pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id); + if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;} + pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP; + pTransInfo->netapi_handle = h; + //issue request + ret = nwal_delIPAddr( + ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, + trans_id, + ifHandle); + if(ret != nwal_OK) + { + *err = NETAPI_ERR_NWAL_ERR0; + printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n", + ret); + pTransInfo->inUse = nwal_FALSE; + return ; + } + //wait here until its done since scheduler isn't running yet most likely.. + // todo: make this handled by scheduler poll later ?? + if(trans_id != NWAL_TRANSID_SPIN_WAIT) + { + n->nwal_local.numPendingCfg++; + while ((volatile) n->nwal_local.numPendingCfg) + { + // if response is there, then this poll squirts out in the CTl poll callback, + // which handles the rest (including decrmenting #pending!! + nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL); + } + } + printf (">netcp cfg: IP i/f deleted\n"); + pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE; + pTransInfo->inUse = nwal_FALSE; + //zap the entry + netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context, + iface_no, + ip_slot); + return ; +} + + +/*************************************************************************/ +/*********************************INTERNAL*******************************/ +/************************************************************************/ + +/*************************************************************** + ********************METCP CMD Reply Callback****************** + ***************************************************************/ +void netapi_NWALCmdCallBack (nwal_AppId appHandle, + uint16_t trans_id, + nwal_RetValue ret) +{ + NetapiNwalTransInfo_t * p_trans; + NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL; + + if(trans_id == NWAL_TRANSID_SPIN_WAIT) + { + netapi_get_global()->nwal_context.numBogusTransIds++; + return; + } + + p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id]; + p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local; + + if(ret != nwal_OK) + { + printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n", + ret); + //todo: atomic inc + netapi_get_global()->nwal_context.numCmdFail++; + } + else + { + //todo: atomic inc + netapi_get_global()->nwal_context.numCmdPass++; + switch(p_trans->transType) + { + case NETAPI_NWAL_HANDLE_TRANS_MAC: + { + if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING) + { + p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN; + } + else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING) + { + p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE; + } + break; + } + case NETAPI_NWAL_HANDLE_TRANS_IP: + { + if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING) + { + p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN; + } + else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING) + { + p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE; + } + break; + } +#if 0 + case TEST_NWAL_HANDLE_TRANS_PORT: + { + if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING) + { + testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN; + } + else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING) + { + testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE; + } + break; + } + case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC: + { + if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING) + { + testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN; + } + else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING) + { + System_printf ("Set Security Assoc Close ACK received for trans_id: %d\n", + testNwLocContext.transInfos[trans_id].transType,trans_id); + nwal_SystemFlush(); + testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE; + } + break; + } +case TEST_NWAL_HANDLE_TRANS_SEC_POLICY: + { + if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING) + { + testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN; + } + else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING) + { + System_printf ("Set Security Policy Close ACK received for trans_id: %d\n", + testNwLocContext.transInfos[trans_id].transType,trans_id); + nwal_SystemFlush(); + testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE; + } + break; + } +#endif + default: + { + printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n", + p_trans->transType,trans_id); + break; + } + } + } + + p_local->numPendingCfg--; + + if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE) + { + p_trans->inUse = nwal_FALSE; + } + +} + + +/*******************************************************/ +/**************stats reply callback**********************/ +/*******************************************************/ +void netapi_NWALCmdPaStatsReply (nwal_AppId appHandle, + nwal_TransID_t trans_id, + paSysStats_t *stats) +{ + NetapiNwalTransInfo_t * p_trans; + NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL; + + if(trans_id == NWAL_TRANSID_SPIN_WAIT) + { + netapi_get_global()->nwal_context.numBogusTransIds++; + return; + } + + p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id]; + p_trans->inUse = nwal_FALSE; + p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local; + + //save a local copy of some stuff*/ + p_local->numL2PktsRecvd=stats->classify1.nPackets; + p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets; +#if 0 + p_local->numL4PktsRecvd=stats->; + p_local->numL4PktsSent=stats->; + p_local->TxErrDrop=stats->; +#endif + //callout result to application !! + if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats); + +} + diff --git a/ti/runtime/netapi/test/net_test.c b/ti/runtime/netapi/test/net_test.c index 11d9c5d..fd0f55d 100755 --- a/ti/runtime/netapi/test/net_test.c +++ b/ti/runtime/netapi/test/net_test.c @@ -1,861 +1,868 @@ -/****************************************** - * 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 - -/*************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"); -} -/*****************************************/ - - -//************for multi pkt burst xfer test in loopback mode -#define TX_BURST 4 -int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK; - -//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 - -}; - -#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 - - - -#if 1 -//#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 */ - - - -#endif -typedef struct stats_t -{ - long itx; //initially generated - long rx; - long tx; - long n_bad; - long n_new; -} STATS_T; - -typedef struct head_t -{ - long ip[5]; - long udp[2]; -} HEAD_T; - -typedef struct key_t -{ - long src_ip; - long dst_ip; - short src_port; - short dst_port; -} KEY_T; - -unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0 -unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1 -nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -nwalIpAddr_t OurIp1={ 10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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; -HEAD_T pkts[NP]; -#define PERSLOW 10 //% of pkts that will not be fastpath'd -int perslow= PERSLOW; - -/******************************************* - *************NETAPI OBJECTS*************** - *****************************************/ -Pktlib_HeapHandle OurHeap; -PKTIO_HANDLE_T *our_chan; -PKTIO_HANDLE_T *netcp_rx_chan; -PKTIO_HANDLE_T *netcp_tx_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_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, 50 //every 50 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); - -/*************************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; -} - return 1; -} - -#define PKT_LEN 1400 -void test_alloc_free(int n) -{ -int i; -Ti_Pkt * b; - -for(i=0;i=4) return NULL; //just gen pkts to warm swtich, so that it knows - //our mac is valid - } - b=Pktlib_allocPacket(OurHeap,PKT_LEN); - 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 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], &testPkt[0],TEST_PKT_LEN); - *p_len = TEST_PKT_LEN; -} - return b; -} - - -/******************************************************/ -/******************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; - - 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 - - - /* check header */ - memcpy(p_head,&p_pkt[14],sizeof(HEAD_T)); - if (!check_header(p_head,&meta[i])) { - stats.n_bad+=1;Pktlib_freePacket(tip); continue; - } - - /* 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); - stats.tx+=1; - } - //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; -printf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired); -tx = netapi_TimerGetFirst(fired_list); -for(i=0;iclassify1.nPackets); - printf("C1 number IPv4 packets: %d\n", pPaStats->classify1.nIpv4Packets); - //printf("C1 number llc/snap fail: %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 of parse fail: %d\n",pPaStats->classify1.nParseFail); - printf("C1 number of command failures: %d\n", pPaStats->classify1.nCommandFail); - printf("C1 number invalid reply dests: %d\n", pPaStats->classify1.nInvalidComReplyDest); - 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 parse failed : %d\n",pPaStats->classify2.nParseFail); - printf ("C2 number Invld Header : %d\n",pPaStats->classify2.nInvldHdr); - printf ("C2 number udp : %d\n",pPaStats->classify2.nUdp); - printf ("C2 number tcp : %d\n",pPaStats->classify2.nTcp); - printf ("C2 number cmd fail : %d\n",pPaStats->classify2.nCommandFail); - printf ("C2 number silent drop : %d\n",pPaStats->classify2.nSilentDiscard); - printf ("C2 number invalid cntrl : %d\n\n",pPaStats->classify2.nInvalidControl); -} -Pktlib_getHeapStats(OurHeap, &numFreeDataPackets, - &numZeroBufferPackets, &numPacketsinGarbage); -printf("heap stats> #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets, - numZeroBufferPackets, numPacketsinGarbage); -//debug = dump timer polling stats -dump_poll_stats(); - - -} - -//****************************************************** -//use scheduling housekeeping callback to generate pkts -//****************************************************** -void house(NETAPI_SCHED_HANDLE_T * s) -{ -Ti_Pkt * tip; -unsigned int len; -nwalTxPktInfo_t meta_tx={0}; -PKTIO_METADATA_T meta = {PKTIO_META_TX,0}; -int err; -static int house_pkts_gened=0; -int p; -unsigned char * pIpHdr,* pData; - -for(p=0;p0) && (! (house_pkts_gened%400)) ) -{ - 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); - if(!tip) { house_pkts_gened +=1; continue; } - - /* set the pkt length */ - Pktlib_setPacketLen(tip, len); - - /* set up meta data */ - meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM); - meta_tx.startOffset = 0; - 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; - meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES; - meta_tx.ploadLen = TEST_PAYLOAD_LEN; - - Pktlib_getDataBuffer(tip,&pData,&len); - pIpHdr = pData + meta_tx.ipOffBytes; - meta_tx.pseudoHdrChecksum = - test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN)); - - /* 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 - pktio_send(netcp_tx_chan,tip,&meta,&err); - if (err == 0) stats.itx +=1; - - house_pkts_gened +=1; - } -} - - -/*************************************** - ********** test driver***************** - ***************************************/ -int main(int argc, char **argv) -{ -int err; -rlim_t oss,ss = 1024*1024; -struct rlimit rl; - -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); -if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n"); -#endif - -if (argc>=2) np2process = atoi(argv[1]); -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);} - - -//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 -} - -/*******************************************/ -/*************NETAPI STARTUP****************/ -/*******************************************/ - -/* create netapi */ -netapi_handle = netapi_init(NETAPI_SYS_MASTER); - -/* open the main heap */ -OurHeap = Pktlib_findHeapByName("netapi"); -if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);} - -/* create a pktio channel */ -our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb, &our_chan_cfg,&err); -if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);} - -/* 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);} -netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg, &err); -if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);} - - -/* create scheduler instance */ -our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err); -if (!our_sched) {printf("sched create failed\n"); exit(1);} - -/* add mac intefaces */ -netcp_cfgCreateMacInterface( - netapi_handle, - &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 -netcp_addIp( - netapi_handle, - 0, - nwal_IPV4, - &OurIp0, - NULL, //all IP - (NETCP_CFG_ROUTE_HANDLE_T) NULL, - &err - ); -if (err) {printf("addip0 failed %d\n",err); exit(1); } -#if 1 -//create a 2nd mac instance -netcp_cfgCreateMacInterface( - netapi_handle, - &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 -netcp_addIp( - netapi_handle, - 1, - nwal_IPV4, - &OurIp1, - NULL, //all IP - (NETCP_CFG_ROUTE_HANDLE_T) NULL, - &err - ); -if (err) {printf("addip1 failed %d\n",err); exit(1); } - -#endif - - 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");} - - -/*********************************************/ -/*****************end NETAPI STARTUP**********/ -/*********************************************/ - - -/******************************************** -* Basic pkt loopback test -*********************************************/ - - -/* 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(np2process +#include +#include +#include + + +#include "trie.h" +#include "string.h" +#include "netapi.h" +#include "pktio.h" +#include + +/*************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"); +} +/*****************************************/ + + +//************for multi pkt burst xfer test in loopback mode +#define TX_BURST 4 +int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK; + +//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 + +}; + +#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 + + + +#if 1 +//#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 */ + + + +#endif +typedef struct stats_t +{ + long itx; //initially generated + long rx; + long tx; + long n_bad; + long n_new; +} STATS_T; + +typedef struct head_t +{ + long ip[5]; + long udp[2]; +} HEAD_T; + +typedef struct key_t +{ + long src_ip; + long dst_ip; + short src_port; + short dst_port; +} KEY_T; + +unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0 +unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1 +nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +nwalIpAddr_t OurIp1={ 10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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; +HEAD_T pkts[NP]; +#define PERSLOW 10 //% of pkts that will not be fastpath'd +int perslow= PERSLOW; + +/******************************************* + *************NETAPI OBJECTS*************** + *****************************************/ +Pktlib_HeapHandle OurHeap; +PKTIO_HANDLE_T *our_chan; +PKTIO_HANDLE_T *netcp_rx_chan; +PKTIO_HANDLE_T *netcp_tx_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_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, 50 //every 50 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; +/*************************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; +} + return 1; +} + +#define PKT_LEN 1400 +void test_alloc_free(int n) +{ +int i; +Ti_Pkt * b; + +for(i=0;i=4) return NULL; //just gen pkts to warm swtich, so that it knows + //our mac is valid + } + b=Pktlib_allocPacket(OurHeap,PKT_LEN); + 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 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], &testPkt[0],TEST_PKT_LEN); + *p_len = TEST_PKT_LEN; +} + return b; +} + + +/******************************************************/ +/******************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; + + 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 + + + /* check header */ + memcpy(p_head,&p_pkt[14],sizeof(HEAD_T)); + if (!check_header(p_head,&meta[i])) { + stats.n_bad+=1;Pktlib_freePacket(tip); continue; + } + + /* 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); + stats.tx+=1; + } + //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; +printf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired); +tx = netapi_TimerGetFirst(fired_list); +for(i=0;iclassify1.nPackets); + printf("C1 number IPv4 packets: %d\n", pPaStats->classify1.nIpv4Packets); + //printf("C1 number llc/snap fail: %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 of parse fail: %d\n",pPaStats->classify1.nParseFail); + printf("C1 number of command failures: %d\n", pPaStats->classify1.nCommandFail); + printf("C1 number invalid reply dests: %d\n", pPaStats->classify1.nInvalidComReplyDest); + 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 parse failed : %d\n",pPaStats->classify2.nParseFail); + printf ("C2 number Invld Header : %d\n",pPaStats->classify2.nInvldHdr); + printf ("C2 number udp : %d\n",pPaStats->classify2.nUdp); + printf ("C2 number tcp : %d\n",pPaStats->classify2.nTcp); + printf ("C2 number cmd fail : %d\n",pPaStats->classify2.nCommandFail); + printf ("C2 number silent drop : %d\n",pPaStats->classify2.nSilentDiscard); + printf ("C2 number invalid cntrl : %d\n\n",pPaStats->classify2.nInvalidControl); +} +Pktlib_getHeapStats(OurHeap, &numFreeDataPackets, + &numZeroBufferPackets, &numPacketsinGarbage); +printf("heap stats> #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets, + numZeroBufferPackets, numPacketsinGarbage); +//debug = dump timer polling stats +dump_poll_stats(); + + +} + +//****************************************************** +//use scheduling housekeeping callback to generate pkts +//****************************************************** +void house(NETAPI_SCHED_HANDLE_T * s) +{ +Ti_Pkt * tip; +unsigned int len; +nwalTxPktInfo_t meta_tx={0}; +PKTIO_METADATA_T meta = {PKTIO_META_TX,0}; +int err; +static int house_pkts_gened=0; +int p; +unsigned char * pIpHdr,* pData; + +for(p=0;p0) && (! (house_pkts_gened%400)) ) +{ + 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); + if(!tip) { house_pkts_gened +=1; continue; } + + /* set the pkt length */ + Pktlib_setPacketLen(tip, len); + + /* set up meta data */ + meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM); + meta_tx.startOffset = 0; + 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; + meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES; + meta_tx.ploadLen = TEST_PAYLOAD_LEN; + + Pktlib_getDataBuffer(tip,&pData,&len); + pIpHdr = pData + meta_tx.ipOffBytes; + meta_tx.pseudoHdrChecksum = + test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN)); + + /* 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 + pktio_send(netcp_tx_chan,tip,&meta,&err); + if (err == 0) stats.itx +=1; + + house_pkts_gened +=1; + } +} + + +/*************************************** + ********** test driver***************** + ***************************************/ +int main(int argc, char **argv) +{ +int err; +rlim_t oss,ss = 1024*1024; +struct rlimit rl; + +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); +if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n"); +#endif + +if (argc>=2) np2process = atoi(argv[1]); +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);} + + +//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 +} + +/*******************************************/ +/*************NETAPI STARTUP****************/ +/*******************************************/ + +/* create netapi */ +netapi_handle = netapi_init(NETAPI_SYS_MASTER); + +/* open the main heap */ +OurHeap = Pktlib_findHeapByName("netapi"); +if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);} + +/* create a pktio channel */ +our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb, &our_chan_cfg,&err); +if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);} + +/* 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);} +netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg, &err); +if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);} + + +/* create scheduler instance */ +our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err); +if (!our_sched) {printf("sched create failed\n"); exit(1);} + +/* add mac intefaces */ +netcp_cfgCreateMacInterface( + netapi_handle, + &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, + &OurIp0, + NULL, //all IP + (NETCP_CFG_ROUTE_HANDLE_T) NULL, + &err + ); +if (err) {printf("addip0 failed %d\n",err); exit(1); } +#if 1 +//create a 2nd mac instance +netcp_cfgCreateMacInterface( + netapi_handle, + &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, + &OurIp1, + NULL, //all IP + (NETCP_CFG_ROUTE_HANDLE_T) NULL, + &err + ); +if (err) {printf("addip1 failed %d\n",err); exit(1); } + +#endif + + 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");} + + +/*********************************************/ +/*****************end NETAPI STARTUP**********/ +/*********************************************/ + + +/******************************************** +* Basic pkt loopback test +*********************************************/ + + +/* 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(np2process