summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9635f3b)
raw | patch | inline | side by side (parent: 9635f3b)
author | Tinku Mannan <tmannan@ti.com> | |
Fri, 21 Sep 2012 15:26:47 +0000 (11:26 -0400) | ||
committer | Tinku Mannan <tmannan@ti.com> | |
Fri, 21 Sep 2012 15:26:47 +0000 (11:26 -0400) |
28 files changed:
index 890ef117cfc14c217a8b09c5eb108ea18945ef18..bc82fc9c51fd09a50a0b0de6c479f16a13f74b33 100755 (executable)
-#*******************************************************************************\r
-#* FILE PURPOSE: Top level makefile for Creating Component Libraries for ARM\r
-#* architectures\r
-#*******************************************************************************\r
-#* FILE NAME: makefile\r
-#*\r
-#* DESCRIPTION: Defines Compiler tools paths, libraries , Build Options \r
-#*\r
-#*\r
-#*******************************************************************************\r
-#*\r
-# (Mandatory) Specify where various tools are installed.\r
-\r
-# Output for prebuilt generated libraries\r
-export ARMV7LIBDIR ?= ./lib\r
-export ARMV7OBJDIR ?= ./obj\r
-\r
-# ROOT Directory\r
-export ROOTDIR := ../../..\r
-\r
-\r
-# INCLUDE Directory\r
-export INCDIR := ../;$(PDK_INSTALL_PATH);$(ROOTDIR)\r
-\r
-# Common Macros used in make\r
-\r
-ifndef RM\r
-export RM = rm -f\r
-endif\r
-\r
-ifndef CP\r
-export CP = cp -p\r
-endif\r
-\r
-export MKDIR = mkdir -p\r
-\r
-ifndef RMDIR\r
-export RMDIR = rm -rf\r
-endif\r
-\r
-ifndef SED\r
-export SED = sed\r
-endif\r
-\r
-ifndef MAKE\r
-export MAKE = make\r
-endif\r
-\r
-# PHONY Targets\r
-.PHONY: lib tests examples all clean\r
-\r
-# all rule\r
-all: .executables\r
-.executables: lib tests examples\r
-lib:\r
-\r
-# Make rule to create $(ARMV7LIBDIR)/libnetapi.a library\r
-lib: $(ARMV7LIBDIR)/libnetapi.a\r
-\r
-$(ARMV7LIBDIR)/libnetapi.a:\r
- -@echo Building library...\r
- @$(MAKE) -f ./build/Makefile $@\r
-\r
-# Rule to clean $(ARMV7LIBDIR)/libnetapi.a library\r
-clean:\r
- -@echo Cleaning netapi package...\r
- @$(MAKE) -f ./build/Makefile $@\r
- @$(MAKE) -f ./test/build/Makefile $@\r
-\r
-# Make rule to create tests\r
-tests:\r
- -@echo compiling tests ...\r
- @$(MAKE) -f ./test/build/Makefile $@\r
-\r
-examples:\r
+#*******************************************************************************
+#* FILE PURPOSE: Top level makefile for Creating Component Libraries for ARM
+#* architectures
+#*******************************************************************************
+#* FILE NAME: makefile
+#*
+#* DESCRIPTION: Defines Compiler tools paths, libraries , Build Options
+#*
+#*
+#*******************************************************************************
+#*
+# (Mandatory) Specify where various tools are installed.
+
+# Output for prebuilt generated libraries
+export ARMV7LIBDIR ?= ./lib
+export ARMV7OBJDIR ?= ./obj
+
+# ROOT Directory
+export ROOTDIR := ../../..
+
+
+# INCLUDE Directory
+export INCDIR := ../;$(PDK_INSTALL_PATH);$(ROOTDIR)
+
+# Common Macros used in make
+
+ifndef RM
+export RM = rm -f
+endif
+
+ifndef CP
+export CP = cp -p
+endif
+
+export MKDIR = mkdir -p
+
+ifndef RMDIR
+export RMDIR = rm -rf
+endif
+
+ifndef SED
+export SED = sed
+endif
+
+ifndef MAKE
+export MAKE = make
+endif
+
+# PHONY Targets
+.PHONY: lib tests examples all clean
+
+# all rule
+all: .executables
+.executables: lib tests examples
+lib:
+
+# Make rule to create $(ARMV7LIBDIR)/libnetapi.a library
+lib: $(ARMV7LIBDIR)/libnetapi.a
+
+$(ARMV7LIBDIR)/libnetapi.a:
+ -@echo Building library...
+ @$(MAKE) -f ./build/Makefile $@
+
+# Rule to clean $(ARMV7LIBDIR)/libnetapi.a library
+clean:
+ -@echo Cleaning netapi package...
+ @$(MAKE) -f ./build/Makefile $@
+ @$(MAKE) -f ./test/build/Makefile $@
+
+# Make rule to create tests
+tests:
+ -@echo compiling tests ...
+ @$(MAKE) -f ./test/build/Makefile $@
+
+examples:
index ab710e4184d88e8148219a2d69264d18ed2b9eb9..40e748671f818d883e97f259c794a36f748ff86b 100755 (executable)
#include "ti/drv/nwal/nwal.h"
#include "netapi_timer.h"
#include "src/netapi_loc.h"
+#include "ti/drv/sa/salld.h"
+#define NETAPI_INFLOW_MODE_ACTIVE 1
+#define NETAPI_SIDEBAND_MODE_ACTIVE 2
+typedef struct NETAPI_SA_STATS_Tag
+{
+ Sa_IpsecStats_t saIpsecStats;
+ Sa_DataModeStats_t dataModeStats;
+ uint8_t mode_active;
+} NETAPI_SA_STATS_T;
/************************************************
**********BUILD TIME CONTROLS *****************
index fc301d62960130b574b4893c2a23917f18a87b82..8981991a57e72136f998deaa87c51c73142eae83 100755 (executable)
-/*******************************\r
- * file: netapi_err.h\r
- * purpose: netapi error codes\r
- **************************************************************\r
- * @file netapi.h\r
- * \r
- * @brief DESCRIPTION: netapi Error Definitions for user space transport\r
- * library\r
- * \r
- * REVISION HISTORY: rev 0.0.1 \r
- *\r
- * Copyright (c) Texas Instruments Incorporated 2010-2011\r
- * \r
- * Redistribution and use in source and binary forms, with or without \r
- * modification, are permitted provided that the following conditions \r
- * are met:\r
- *\r
- * Redistributions of source code must retain the above copyright \r
- * notice, this list of conditions and the following disclaimer.\r
- *\r
- * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the \r
- * documentation and/or other materials provided with the \r
- * distribution.\r
- *\r
- * Neither the name of Texas Instruments Incorporated nor the names of\r
- * its contributors may be used to endorse or promote products derived\r
- * from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-\r
- ******************************/\r
-\r
-#ifndef __NETAPI_ERR__\r
-#define __NETAPI_ERR__\r
-/**\r
- * @defgroup NETAPI_RetValue NETAPI Return Codes\r
- */\r
-/** @ingroup NETAPI_RetValue */\r
-\r
-/**\r
- * @def NETAPI_ERR_OK\r
- * No error \r
- */\r
-#define NETAPI_ERR_OK 0\r
-/**\r
- * @ingroup NETAPI_RetValue\r
- * @def NETAPI_ERR_NOMEM\r
- * @brief out of memory error \r
- */\r
-#define NETAPI_ERR_NOMEM -1\r
-/**\r
-* @ingroup NETAPI_RetValue\r
- * @def NETAPI_ERR_BAD_INPUT\r
- * arguments or configuraiton is invalid\r
- */\r
-#define NETAPI_ERR_BAD_INPUT -2\r
-/**\r
-* @ingroup NETAPI_RetValue\r
- * @def NETAPI_ERR_QLLD \r
- * QUEUE MANAGER Reports an error\r
- */\r
-#define NETAPI_ERR_QLLD -3\r
-/**\r
-* @ingroup NETAPI_RetValue\r
- * @def NETAPI_ERR_NOTFOUND\r
- * the resource cannot be located\r
- */\r
-#define NETAPI_ERR_NOTFOUND -4\r
-/**\r
-* @ingroup NETAPI_RetValue\r
- * @def NETAPI_ERR_BUSY\r
- * Temporarily out of resources or resource leak\r
- */\r
-#define NETAPI_ERR_BUSY -5 \r
-/**\r
-* @ingroup NETAPI_RetValue\r
- * @def NETAPI_ERR_NWAL_ERR0\r
- * NWAL subsytem reports error \r
- */\r
-#define NETAPI_ERR_NWAL_ERR0 -6\r
-/**\r
-* @ingroup NETAPI_RetValue\r
- * @def NETAPI_ERR_NOT_IMLEMENTED_\r
- * Feature not implemented in this version \r
- */\r
-#define NETAPI_ERR_NOT_IMPLEMENTED -7\r
-/**\r
-* @ingroup NETAPI_RetValue\r
- * @def NETAPI_ERR_NORES\r
- * no free (hw) resources available \r
- */\r
-#define NETAPI_ERR_NORES -8\r
-/**\r
-* @ingroup NETAPI_RetValue\r
- * @def NETAPI_ERR_ALREADY_CANCELLED\r
- * timer has already been cancelled\r
- */\r
-#define NETAPI_ERR_ALREADY_CANCELLED -100\r
-/**\r
-* @ingroup NETAPI_RetValue\r
- * @def NETAPI_ERR_NWAL_TX_ERR\r
- * error trying to send to NWAL. \r
- */\r
-#define NETAPI_ERR_NWAL_TX_ERR -65536\r
-#endif\r
+/*******************************
+ * file: netapi_err.h
+ * purpose: netapi error codes
+ **************************************************************
+ * @file netapi.h
+ *
+ * @brief DESCRIPTION: netapi Error Definitions 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 __NETAPI_ERR__
+#define __NETAPI_ERR__
+/**
+ * @defgroup NETAPI_RetValue NETAPI Return Codes
+ */
+/** @ingroup NETAPI_RetValue */
+
+/**
+ * @def NETAPI_ERR_OK
+ * No error
+ */
+#define NETAPI_ERR_OK 0
+/**
+ * @ingroup NETAPI_RetValue
+ * @def NETAPI_ERR_NOMEM
+ * @brief out of memory error
+ */
+#define NETAPI_ERR_NOMEM -1
+/**
+* @ingroup NETAPI_RetValue
+ * @def NETAPI_ERR_BAD_INPUT
+ * arguments or configuraiton is invalid
+ */
+#define NETAPI_ERR_BAD_INPUT -2
+/**
+* @ingroup NETAPI_RetValue
+ * @def NETAPI_ERR_QLLD
+ * QUEUE MANAGER Reports an error
+ */
+#define NETAPI_ERR_QLLD -3
+/**
+* @ingroup NETAPI_RetValue
+ * @def NETAPI_ERR_NOTFOUND
+ * the resource cannot be located
+ */
+#define NETAPI_ERR_NOTFOUND -4
+/**
+* @ingroup NETAPI_RetValue
+ * @def NETAPI_ERR_BUSY
+ * Temporarily out of resources or resource leak
+ */
+#define NETAPI_ERR_BUSY -5
+/**
+* @ingroup NETAPI_RetValue
+ * @def NETAPI_ERR_NWAL_ERR0
+ * NWAL subsytem reports error
+ */
+#define NETAPI_ERR_NWAL_ERR0 -6
+/**
+* @ingroup NETAPI_RetValue
+ * @def NETAPI_ERR_NOT_IMLEMENTED_
+ * Feature not implemented in this version
+ */
+#define NETAPI_ERR_NOT_IMPLEMENTED -7
+/**
+* @ingroup NETAPI_RetValue
+ * @def NETAPI_ERR_NORES
+ * no free (hw) resources available
+ */
+#define NETAPI_ERR_NORES -8
+/**
+* @ingroup NETAPI_RetValue
+ * @def NETAPI_ERR_ALREADY_CANCELLED
+ * timer has already been cancelled
+ */
+#define NETAPI_ERR_ALREADY_CANCELLED -100
+/**
+* @ingroup NETAPI_RetValue
+ * @def NETAPI_ERR_NWAL_TX_ERR
+ * error trying to send to NWAL.
+ */
+#define NETAPI_ERR_NWAL_TX_ERR -65536
+#endif
index 485488ffe076bd3dfd3e9ce3f497057862ccf399..f8375f8c22c511febcef1b9231d4b981d8206a15 100755 (executable)
-/***********************************\r
- * File: netapi_sched.h\r
- * Purpose: netapi scheduler module\r
- **************************************************************\r
- * FILE: netapi_sched.h\r
- * \r
- * DESCRIPTION: netapi sample event scheduler header file for \r
- * user space transport library\r
- * \r
- * REVISION HISTORY: rev 0.0.1 \r
- *\r
- * Copyright (c) Texas Instruments Incorporated 2010-2011\r
- * \r
- * Redistribution and use in source and binary forms, with or without \r
- * modification, are permitted provided that the following conditions \r
- * are met:\r
- *\r
- * Redistributions of source code must retain the above copyright \r
- * notice, this list of conditions and the following disclaimer.\r
- *\r
- * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the \r
- * documentation and/or other materials provided with the \r
- * distribution.\r
- *\r
- * Neither the name of Texas Instruments Incorporated nor the names of\r
- * its contributors may be used to endorse or promote products derived\r
- * from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-\r
- ***********************************/\r
-#ifndef __NETAPI_SCHED__\r
-#define __NETAPI_SCHED__\r
-#include "netapi.h"\r
-\r
-/****************************\r
- **********CONTEXT**********\r
- ****************************/\r
-struct NETAPI_SCHED_HANDLE_Tag;\r
-\r
-typedef void (*NETAPI_SCHED_CB)(struct NETAPI_SCHED_HANDLE_Tag *h);\r
-\r
-\r
-typedef struct NETAPI_SCHED_CONFIG_Tag\r
-{\r
-int valid_flags; //which is being configured\r
-#define NETAPI_SCHED_DURATION 0x1\r
-#define NETAPI_SCHED_POWER 0x2\r
-#define NETAPI_SCHED_FINE 0x4 //future\r
-#define NETAPI_SCHED_CBV 0x8 //callback\r
-\r
-/*----duration------*/\r
-uint64_t duration; //0=forever or #tics to run for \r
-#define NETAPI_SCHED_FOREVER 0L\r
-\r
-/*-----house callback-----*/\r
-NETAPI_SCHED_CB house_cb;\r
-\r
-uint32_t interval; // how many poll loop intervals after which to call the house keeping function \r
-\r
-\r
-/*------power control-------*/\r
-int power_control; //0= always on, >0 = duty cycle \r
-#define NETAPI_SCHED_POWER_ALWAYS_OFF 0 //drop to idle\r
-#define NETAPI_SCHED_POWER_ALWAYS_ON 100 //always runs, no drop to idle\r
-\r
-int idle_time; //in ticks\r
-\r
-/*-----fine control-----*/\r
-//future..\r
-\r
-} NETAPI_SCHED_CONFIG_T;\r
-\r
-\r
-/* the schedule context */\r
-typedef struct NETAPI_SCHED_HANDLE_Tag\r
-{\r
- volatile int state; //0= shutdown, 1= shutting down, 2=active\r
-#define NETAPI_SCHED_STATE_SHUT 0\r
-#define NETAPI_SCHED_STATE_SHUTTING 1\r
-#define NETAPI_SCHED_STATE_ACTIVE 2\r
- void * back; //pointer back to netapi handle\r
- NETAPI_SCHED_CONFIG_T config;\r
- uint64_t start; /* start time */ \r
- volatile int shutdown_reason;\r
- volatile uint64_t shutdown_time;\r
-\r
-} NETAPI_SCHED_HANDLE_T;\r
-\r
-/* how to shut down */\r
-typedef struct NETAPI_SCHED_SHUTDOWN_Tag\r
-{\r
-int shutdown_type;\r
-#define NETAPI_SCHED_SHUTDOWN_NOW 0\r
-#define NETAPI_SCHED_SHUTDOWN_TO 1\r
-#define NETAPI_SCHED_SHUTDOWN_NEXT_IDLE 2\r
-int timeout; //ticks from now to close\r
-\r
-} NETAPI_SCHED_SHUTDOWN_T;\r
-\r
-/****************************\r
- **************API **********\r
- ****************************/\r
-\r
-/* open a scheduling contex */\r
-NETAPI_SCHED_HANDLE_T * netapi_schedOpen(NETAPI_T n, NETAPI_SCHED_CONFIG_T * p_config, int *p_err);\r
-\r
-/* re-configure a scheduling context */\r
-int netapi_schedControl(NETAPI_SCHED_HANDLE_T *s, NETAPI_SCHED_CONFIG_T *p_config, int *p_err);\r
-\r
-/* return codes for wait_for_events() */\r
-#define NETAPI_SCHED_RETURN_ERR 0 //unknown, err\r
-#define NETAPI_SCHED_RETURN_TO 1 // returned after timeout\r
-#define NETAPI_SCHED_RETURN_SHUTDOWN 2 //returned after shutdown\r
-\r
-/* main entry point. caller gives up control to scheduler */\r
-int netapi_schedWaitForEvents(NETAPI_SCHED_HANDLE_T *s, int * p_err);\r
-\r
-/* shutdown scheduler context */\r
-int netapi_schedShutdown(NETAPI_SCHED_HANDLE_T * s, NETAPI_SCHED_SHUTDOWN_T * p_close, int *p_err);\r
-\r
-static NETAPI_T netapi_schedGetNetapiHandle(NETAPI_SCHED_HANDLE_T *s)\r
- { return (NETAPI_T)s->back;}\r
-#endif\r
+/***********************************
+ * File: netapi_sched.h
+ * Purpose: netapi scheduler module
+ **************************************************************
+ * FILE: netapi_sched.h
+ *
+ * DESCRIPTION: netapi sample event scheduler 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 __NETAPI_SCHED__
+#define __NETAPI_SCHED__
+#include "netapi.h"
+
+/****************************
+ **********CONTEXT**********
+ ****************************/
+struct NETAPI_SCHED_HANDLE_Tag;
+
+typedef void (*NETAPI_SCHED_CB)(struct NETAPI_SCHED_HANDLE_Tag *h);
+
+
+typedef struct NETAPI_SCHED_CONFIG_Tag
+{
+int valid_flags; //which is being configured
+#define NETAPI_SCHED_DURATION 0x1
+#define NETAPI_SCHED_POWER 0x2
+#define NETAPI_SCHED_FINE 0x4 //future
+#define NETAPI_SCHED_CBV 0x8 //callback
+
+/*----duration------*/
+uint64_t duration; //0=forever or #tics to run for
+#define NETAPI_SCHED_FOREVER 0L
+
+/*-----house callback-----*/
+NETAPI_SCHED_CB house_cb;
+
+uint32_t interval; // how many poll loop intervals after which to call the house keeping function
+
+
+/*------power control-------*/
+int power_control; //0= always on, >0 = duty cycle
+#define NETAPI_SCHED_POWER_ALWAYS_OFF 0 //drop to idle
+#define NETAPI_SCHED_POWER_ALWAYS_ON 100 //always runs, no drop to idle
+
+int idle_time; //in ticks
+
+/*-----fine control-----*/
+//future..
+
+} NETAPI_SCHED_CONFIG_T;
+
+
+/* the schedule context */
+typedef struct NETAPI_SCHED_HANDLE_Tag
+{
+ volatile int state; //0= shutdown, 1= shutting down, 2=active
+#define NETAPI_SCHED_STATE_SHUT 0
+#define NETAPI_SCHED_STATE_SHUTTING 1
+#define NETAPI_SCHED_STATE_ACTIVE 2
+ void * back; //pointer back to netapi handle
+ NETAPI_SCHED_CONFIG_T config;
+ uint64_t start; /* start time */
+ volatile int shutdown_reason;
+ volatile uint64_t shutdown_time;
+
+} NETAPI_SCHED_HANDLE_T;
+
+/* how to shut down */
+typedef struct NETAPI_SCHED_SHUTDOWN_Tag
+{
+int shutdown_type;
+#define NETAPI_SCHED_SHUTDOWN_NOW 0
+#define NETAPI_SCHED_SHUTDOWN_TO 1
+#define NETAPI_SCHED_SHUTDOWN_NEXT_IDLE 2
+int timeout; //ticks from now to close
+
+} NETAPI_SCHED_SHUTDOWN_T;
+
+/****************************
+ **************API **********
+ ****************************/
+
+/* open a scheduling contex */
+NETAPI_SCHED_HANDLE_T * netapi_schedOpen(NETAPI_T n, NETAPI_SCHED_CONFIG_T * p_config, int *p_err);
+
+/* re-configure a scheduling context */
+int netapi_schedControl(NETAPI_SCHED_HANDLE_T *s, NETAPI_SCHED_CONFIG_T *p_config, int *p_err);
+
+/* return codes for wait_for_events() */
+#define NETAPI_SCHED_RETURN_ERR 0 //unknown, err
+#define NETAPI_SCHED_RETURN_TO 1 // returned after timeout
+#define NETAPI_SCHED_RETURN_SHUTDOWN 2 //returned after shutdown
+
+/* main entry point. caller gives up control to scheduler */
+int netapi_schedWaitForEvents(NETAPI_SCHED_HANDLE_T *s, int * p_err);
+
+/* shutdown scheduler context */
+int netapi_schedShutdown(NETAPI_SCHED_HANDLE_T * s, NETAPI_SCHED_SHUTDOWN_T * p_close, int *p_err);
+
+static NETAPI_T netapi_schedGetNetapiHandle(NETAPI_SCHED_HANDLE_T *s)
+ { return (NETAPI_T)s->back;}
+void netapi_sched_get_stats(unsigned long long * p_pkts,
+ unsigned long long * p_cycles,
+ unsigned long long * p_ccycles);
+#endif
#include "netapi.h"
#include "ti/runtime/pktlib/pktlib.h"
#include "ti/drv/nwal/nwal.h"
-
+#include <ti/drv/sa/salld.h>
// To hold SA info */
typedef struct NETAPI_SEC_SA_INFO_tag
index 033b757bf81c1496175a629117349b0760413aa6..83aedd4b675ae72e8e020c4a0db0c85173a341a5 100755 (executable)
-/************************************************\r
- *FILE: netapi_timer.h\r
- *Purpose: netapi timer related functions\r
- **************************************************************\r
- * @file netapi_timer.h\r
- * \r
- * @breif DESCRIPTION: netapi timer library header file for user space transport\r
- * library\r
- * \r
- * REVISION HISTORY: rev 0.0.1 \r
- *\r
- * Copyright (c) Texas Instruments Incorporated 2010-2011\r
- * \r
- * Redistribution and use in source and binary forms, with or without \r
- * modification, are permitted provided that the following conditions \r
- * are met:\r
- *\r
- * Redistributions of source code must retain the above copyright \r
- * notice, this list of conditions and the following disclaimer.\r
- *\r
- * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the \r
- * documentation and/or other materials provided with the \r
- * distribution.\r
- *\r
- * Neither the name of Texas Instruments Incorporated nor the names of\r
- * its contributors may be used to endorse or promote products derived\r
- * from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-\r
- ***********************************************/\r
-\r
-/** @mainpage Netapi Timer Lib \r
- *\r
- * @section intro Introduction\r
- *\r
- * The network API provides a user space interface to timers\r
- * - a function to read a hw provided 64bit time stamp, @ref netapi_getTimestamp\r
- * This returns a tick running at 1/6 cpu frequency\r
- * - functions to create or open timer groups: @ref netapi_TimerGroupCreateTimer\r
- * and @ref netapi_TimerGroupOpenTimer. A timer group\r
- * is a group of timers with the same characteristics:\r
- * -> local or global\r
- * -> timer resolution (msc, 10 msc, etc)\r
- * -> expect to fire or expect to cancel\r
- * -> the same call back function for fired timers\r
- * - functions to close or delete timer groups\r
- * - function to start a timer, @ref netapi_TimerGroupStartTimer\r
- * - function to cancel a timer, @ref netapi_TimerGroupCancelTimer\r
- * - function to poll a timer group, or all timer groups registered to a NETAPI \r
- * instance\r
- * \par\r
- * NOTE:\r
- * (C) Copyright 2010-2011 Texas Instruments, Inc.\r
- * \par\r
- */\r
-\r
-\r
-#ifndef __NETAPI_TIMER__H\r
-#define __NETAPI_TIMER__H\r
-#include "netapi.h"\r
-\r
-extern volatile unsigned long * t64_virt_addr;\r
-extern unsigned int cpu_cycles_sec;\r
-\r
-//return hw timer clock ticks per second\r
-unsigned long t64_ticks_sec(void);\r
-#define netapi_getTicksPerSec t64_ticks_sec\r
-\r
-\r
-/** @ingroup netapi_api_functions */\r
-\r
-/*\r
- * @brief API returns a 64bit h/w timestamp \r
- *\r
- * @details reads a h/w timer (TIMER64 on Appleton SOC) and returns a 64 bit time stamp \r
- * timer runs at @ref t64_ticks_sec. Nominally this should be 1/6 CPU clk (@ref cpu_cycles_sec)\r
- * \r
- * @param[in] none \r
- * @retval unsigned long long timestamp (64 buts) \r
- * @pre @ref netapi_init \r
- */\r
-//return 64 bit timestamp from hw timer\r
-volatile static inline unsigned long long netapi_getTimestamp(void) \r
-{\r
- volatile unsigned long long t1;\r
- volatile unsigned long long t2;\r
- unsigned long long val;\r
- t1 = t64_virt_addr[0x10/4]; //lo\r
- t2 = t64_virt_addr[0x14/4]; //hi\r
- val = ((unsigned long long) t2) <<32 | t1;\r
- return val;\r
-}\r
-\r
-/******************************************************/\r
-/*******************TIMER API***************************/\r
-/******************************************************/\r
-typedef void * NETAPI_TIMER_GROUP_HANDLE_T; \r
-typedef void * NETAPI_TIMER_T;\r
-typedef void * NETAPI_TIMER_LIST_T;\r
-\r
-/* timer filter values */\r
-typedef int NETAPI_TIMER_FILTER_T;\r
-#define NETAPI_TIMER_NA (void*) NULL\r
-#define NETAPI_TIMER_FILTER_GLOBAL 0x1\r
-#define NETAPI_TIMER_FILTER_LOCAL 0x2\r
-#define NETAPI_TIMER_FILTER_E2F 0x4\r
-#define NETAPI_TIMER_FILTER_E2C 0x8\r
-#define NETAPI_TIMER_FITLER_ALL 0xf\r
-\r
-//iterator on TIMER_LIST_T\r
-NETAPI_TIMER_T netapi_TimerGetFirst( NETAPI_TIMER_LIST_T list);\r
-NETAPI_TIMER_T netapi_TimerGetNext( NETAPI_TIMER_LIST_T list,NETAPI_TIMER_T prev);\r
-void * netapi_TimerGetCookie(NETAPI_TIMER_T timer);\r
-unsigned long long netapi_TimerGetTs(NETAPI_TIMER_T timer); //debug\r
-\r
-/*\r
- * @brief API callback for timer expiration \r
- *\r
- * @details this function, provided by application, is registered by application \r
- * when timer group is created. It is called by timer library when a timer or set of timers\r
- * expire. The timer list can be walled with iterators: @ref netapi_TimerGetFirst, \r
- * @ref netapi_TimerGetNext. The timer id or "cookie" can be accessed via @ref netapi_TimerGetCookie\r
- * NOTE: callback should check for cookie==NULL since timer could be cancelled as it is being fired\r
- * @param[in] @ref NETAPI_TIMER_GROUP_HANDLE_T : the handle to the timer group\r
- * @param[in] int : the number of timers that have fired \r
- * @param[in] @ref NETAPI_TIMER_LIST_T : the list of timers that hace expired \r
- * @param[in] uint64_t : the current time\r
- * @retval none \r
- * @pre @ref netapi_init , @ref netapi_TimerGroupCreate, @ref netapi_TimerGroupStartTimer\r
- */\r
-//timer callback\r
-typedef void (*NETAPI_TIMER_CB_T) (\r
- NETAPI_TIMER_GROUP_HANDLE_T th, //timer group\r
- int n_fired, //# timers fired\r
- NETAPI_TIMER_LIST_T fired_list, //the list of fired timers. Access via iterators above\r
- uint64_t currentTime); //current timestamp\r
-\r
-/*\r
-* @brief API for Timer Group Creation \r
- *\r
- * @details this function is used to create a timer group. A timer group is a block of timers\r
- * that share the same characteristics.\r
- * @param[in] @ref NETAPI_T : the handle to the NETAPI Instance \r
- * @param[in] char * : the name of the timer\r
- * @param[in] @ref NETAPI_TIMER_CB_T : the callback function\r
- * @param[in] int : local (=1 if this timer group is local to this netapi instance, =0 if global)\r
- * @param[in] int : exp2cancel. (=1 if this timer group is expected to be cancelled, =0 otherwise))\r
- * @param[in] int : the timer group 'tick'. This is the group timer resolution in hw timestamp units. \r
- * Eg for 10 msc , enter @ref netapi_getTicksPerSec()/100\r
- * @param[in] int : timerTolerence in hw timestamp ticks. This is FUTURE.\r
- * @param[in] int : maxTimers - the max number of timers that can be handled by the group.\r
- * @param[in] int* : pointer to error return\r
- * @retval @ref NETAPI_TIMER_GROUP_HANDLE_T : handle for this timer group \r
- * @pre @ref netapi_init \r
- */\r
-//create a timer group\r
-NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupCreate(\r
- NETAPI_T netHandle, //netapi instance\r
- char * name, //name of the timer block\r
- NETAPI_TIMER_CB_T cb, //the callback function\r
- int local, //1 if timers local to thread\r
- int exp2cancel,//1 if expect to cancel\r
- int timerTicksPerGroupTick, //resolution for this timer block, in hw timer ticks\r
- int timerTolerence, //tolerence for this timer block, in hw timer ticksi [FUTURE]\r
- int maxTimers, //max # of timer objects for this group\r
- int *pErr);\r
-\r
-//open a [global] timer group [FUTURE]\r
-NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupOpen(\r
- NETAPI_T netHandle,\r
- char * name,\r
- NETAPI_TIMER_CB_T cb,\r
- int *pErr);\r
-\r
-/*\r
-* @brief API for Start a Timer \r
- *\r
- * @details this function is used to start a timer. When it expires, the @ref NETAPI_TIMER_CB_T\r
- * will be called.\r
- * @param[in] @ref NATAPI_TIMER_GROUP_HANDLE_T : the handle to the timer group \r
- * @param[in] void * : application provided timer id or cookie. MUST NOT BE NULL!!!\r
- * @param[in] uint64_t : offset from current time when to fire this timer. This offset MUST be in\r
- * units of timer group ticks (set at create time). Eg. For 10 msc timer group,\r
- * offset2fire =1 => timer is to fire in 10 msc.\r
- * @param[in] int* : pointer to error return\r
- * @retval @ref NETAPI_TIMER_T : handle for this timer. Used to reference the timer for cancel\r
- * @pre @ref netapi_init , @ref netapi_TimerGroupCreate\r
- */\r
-//start an individual timer\r
-NETAPI_TIMER_T netapi_TimerGroupStartTimer(\r
- NETAPI_TIMER_GROUP_HANDLE_T th, //the group handle\r
- void * cookie, //user id -> CANNONT BE NULL \r
- uint64_t offs2fire, //offset in timerGroup ticks (eg msc)\r
- int * pErr); //error return\r
-\r
-/*\r
-* @brief API for Cancel a Timer \r
- *\r
- * @details this function is used to cancel a timer. When it expires, the @ref NETAPI_TIMER_CB_T\r
- * will be called.\r
- * @param[in] @ref NATAPI_TIMER_GROUP_HANDLE_T : the handle to the timer group \r
- * @param[in] @ref NATAPI_TIMER_T : the handle to the individual timer to cancel\r
- * @param[in] int* : pointer to error return\r
- * @retval none \r
- * @pre @ref netapi_TimerGroupStartTimer\r
- */\r
-//Cancel a timer\r
-void netapi_TimerGroupCancel(\r
- NETAPI_TIMER_GROUP_HANDLE_T th,\r
- NETAPI_TIMER_T timerId,\r
- int *pErr);\r
-\r
-//close an opened timer group\r
-void netapi_TimerGroupClose(\r
- NETAPI_TIMER_GROUP_HANDLE_T th,\r
- int *pErr);\r
-\r
-//close an opened timer group\r
-void netapi_TimerGroupDelete(\r
- NETAPI_TIMER_GROUP_HANDLE_T th,\r
- int *pErr);\r
-\r
-//extract netapi handle from timer group handle\r
-NETAPI_T netap_TimerGroupGetNH( NETAPI_TIMER_GROUP_HANDLE_T th);\r
-\r
-//poll a specific timer group\r
-int netapi_TimerGroupPoll(NETAPI_TIMER_GROUP_HANDLE_T th, int maxTimers);\r
-\r
-/*\r
-* @brief API for Polling all timer groups attached to an instance \r
- *\r
- * @details this function is used to poll all or a specified subset of the timer groups of an \r
- * instance. A mask can be set to filter which categories of timer groups (local vs global etc)\r
- * to poll. The approximate max # of timers to process can also be set.\r
- * @param[in] @ref NATAPI_T : the handle of the netapi instance. \r
- * @param[in] @ref NATAPI_TIMER_FILTER_T : the bit mask of timer group types to poll \r
- * @param[in] int : approximate max number of timers to process. NOTE: this can be used to\r
- * coarsely control how many timers to process. In general, all timers that have been \r
- * hashed into the same cell and have expired will be processed regardless of the\r
- * maxTmers setting.. [FUTURE]\r
- * @retval none \r
- * @pre @ref netapi_init, @ref netapi_TimerGroupCreate\r
- */\r
-\r
-//poll all timers\r
-int netapi_TimerGroupPollAll(NETAPI_T nh, NETAPI_TIMER_FILTER_T f, int maxTimers);\r
-\r
-/*****************END API*********************************/\r
-\r
-\r
-#endif\r
+/************************************************
+ *FILE: netapi_timer.h
+ *Purpose: netapi timer related functions
+ **************************************************************
+ * @file netapi_timer.h
+ *
+ * @breif DESCRIPTION: netapi timer library 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.
+
+ ***********************************************/
+
+/** @mainpage Netapi Timer Lib
+ *
+ * @section intro Introduction
+ *
+ * The network API provides a user space interface to timers
+ * - a function to read a hw provided 64bit time stamp, @ref netapi_getTimestamp
+ * This returns a tick running at 1/6 cpu frequency
+ * - functions to create or open timer groups: @ref netapi_TimerGroupCreateTimer
+ * and @ref netapi_TimerGroupOpenTimer. A timer group
+ * is a group of timers with the same characteristics:
+ * -> local or global
+ * -> timer resolution (msc, 10 msc, etc)
+ * -> expect to fire or expect to cancel
+ * -> the same call back function for fired timers
+ * - functions to close or delete timer groups
+ * - function to start a timer, @ref netapi_TimerGroupStartTimer
+ * - function to cancel a timer, @ref netapi_TimerGroupCancelTimer
+ * - function to poll a timer group, or all timer groups registered to a NETAPI
+ * instance
+ * \par
+ * NOTE:
+ * (C) Copyright 2010-2011 Texas Instruments, Inc.
+ * \par
+ */
+
+
+#ifndef __NETAPI_TIMER__H
+#define __NETAPI_TIMER__H
+#include "netapi.h"
+
+extern volatile unsigned long * t64_virt_addr;
+extern unsigned int cpu_cycles_sec;
+
+//return hw timer clock ticks per second
+unsigned long t64_ticks_sec(void);
+#define netapi_getTicksPerSec t64_ticks_sec
+
+
+/** @ingroup netapi_api_functions */
+
+/*
+ * @brief API returns a 64bit h/w timestamp
+ *
+ * @details reads a h/w timer (TIMER64 on Appleton SOC) and returns a 64 bit time stamp
+ * timer runs at @ref t64_ticks_sec. Nominally this should be 1/6 CPU clk (@ref cpu_cycles_sec)
+ *
+ * @param[in] none
+ * @retval unsigned long long timestamp (64 buts)
+ * @pre @ref netapi_init
+ */
+//return 64 bit timestamp from hw timer
+volatile static inline unsigned long long netapi_getTimestamp(void)
+{
+ volatile unsigned long long t1;
+ volatile unsigned long long t2;
+ unsigned long long val;
+ t1 = t64_virt_addr[0x10/4]; //lo
+ t2 = t64_virt_addr[0x14/4]; //hi
+ val = ((unsigned long long) t2) <<32 | t1;
+ return val;
+}
+
+/******************************************************/
+/*******************TIMER API***************************/
+/******************************************************/
+typedef void * NETAPI_TIMER_GROUP_HANDLE_T;
+typedef void * NETAPI_TIMER_T;
+typedef void * NETAPI_TIMER_LIST_T;
+
+/* timer filter values */
+typedef int NETAPI_TIMER_FILTER_T;
+#define NETAPI_TIMER_NA (void*) NULL
+#define NETAPI_TIMER_FILTER_GLOBAL 0x1
+#define NETAPI_TIMER_FILTER_LOCAL 0x2
+#define NETAPI_TIMER_FILTER_E2F 0x4
+#define NETAPI_TIMER_FILTER_E2C 0x8
+#define NETAPI_TIMER_FITLER_ALL 0xf
+
+//iterator on TIMER_LIST_T
+NETAPI_TIMER_T netapi_TimerGetFirst( NETAPI_TIMER_LIST_T list);
+NETAPI_TIMER_T netapi_TimerGetNext( NETAPI_TIMER_LIST_T list,NETAPI_TIMER_T prev);
+void * netapi_TimerGetCookie(NETAPI_TIMER_T timer);
+unsigned long long netapi_TimerGetTs(NETAPI_TIMER_T timer); //debug
+
+/*
+ * @brief API callback for timer expiration
+ *
+ * @details this function, provided by application, is registered by application
+ * when timer group is created. It is called by timer library when a timer or set of timers
+ * expire. The timer list can be walled with iterators: @ref netapi_TimerGetFirst,
+ * @ref netapi_TimerGetNext. The timer id or "cookie" can be accessed via @ref netapi_TimerGetCookie
+ * NOTE: callback should check for cookie==NULL since timer could be cancelled as it is being fired
+ * @param[in] @ref NETAPI_TIMER_GROUP_HANDLE_T : the handle to the timer group
+ * @param[in] int : the number of timers that have fired
+ * @param[in] @ref NETAPI_TIMER_LIST_T : the list of timers that hace expired
+ * @param[in] uint64_t : the current time
+ * @retval none
+ * @pre @ref netapi_init , @ref netapi_TimerGroupCreate, @ref netapi_TimerGroupStartTimer
+ */
+//timer callback
+typedef void (*NETAPI_TIMER_CB_T) (
+ NETAPI_TIMER_GROUP_HANDLE_T th, //timer group
+ int n_fired, //# timers fired
+ NETAPI_TIMER_LIST_T fired_list, //the list of fired timers. Access via iterators above
+ uint64_t currentTime); //current timestamp
+
+/*
+* @brief API for Timer Group Creation
+ *
+ * @details this function is used to create a timer group. A timer group is a block of timers
+ * that share the same characteristics.
+ * @param[in] @ref NETAPI_T : the handle to the NETAPI Instance
+ * @param[in] char * : the name of the timer
+ * @param[in] @ref NETAPI_TIMER_CB_T : the callback function
+ * @param[in] int : local (=1 if this timer group is local to this netapi instance, =0 if global)
+ * @param[in] int : exp2cancel. (=1 if this timer group is expected to be cancelled, =0 otherwise))
+ * @param[in] int : the timer group 'tick'. This is the group timer resolution in hw timestamp units.
+ * Eg for 10 msc , enter @ref netapi_getTicksPerSec()/100
+ * @param[in] int : timerTolerence in hw timestamp ticks. This is FUTURE.
+ * @param[in] int : maxTimers - the max number of timers that can be handled by the group.
+ * @param[in] int* : pointer to error return
+ * @retval @ref NETAPI_TIMER_GROUP_HANDLE_T : handle for this timer group
+ * @pre @ref netapi_init
+ */
+//create a timer group
+NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupCreate(
+ NETAPI_T netHandle, //netapi instance
+ char * name, //name of the timer block
+ NETAPI_TIMER_CB_T cb, //the callback function
+ int local, //1 if timers local to thread
+ int exp2cancel,//1 if expect to cancel
+ int timerTicksPerGroupTick, //resolution for this timer block, in hw timer ticks
+ int timerTolerence, //tolerence for this timer block, in hw timer ticksi [FUTURE]
+ int maxTimers, //max # of timer objects for this group
+ int *pErr);
+
+//open a [global] timer group [FUTURE]
+NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupOpen(
+ NETAPI_T netHandle,
+ char * name,
+ NETAPI_TIMER_CB_T cb,
+ int *pErr);
+
+/*
+* @brief API for Start a Timer
+ *
+ * @details this function is used to start a timer. When it expires, the @ref NETAPI_TIMER_CB_T
+ * will be called.
+ * @param[in] @ref NATAPI_TIMER_GROUP_HANDLE_T : the handle to the timer group
+ * @param[in] void * : application provided timer id or cookie. MUST NOT BE NULL!!!
+ * @param[in] uint64_t : offset from current time when to fire this timer. This offset MUST be in
+ * units of timer group ticks (set at create time). Eg. For 10 msc timer group,
+ * offset2fire =1 => timer is to fire in 10 msc.
+ * @param[in] int* : pointer to error return
+ * @retval @ref NETAPI_TIMER_T : handle for this timer. Used to reference the timer for cancel
+ * @pre @ref netapi_init , @ref netapi_TimerGroupCreate
+ */
+//start an individual timer
+NETAPI_TIMER_T netapi_TimerGroupStartTimer(
+ NETAPI_TIMER_GROUP_HANDLE_T th, //the group handle
+ void * cookie, //user id -> CANNONT BE NULL
+ uint64_t offs2fire, //offset in timerGroup ticks (eg msc)
+ int * pErr); //error return
+
+/*
+* @brief API for Cancel a Timer
+ *
+ * @details this function is used to cancel a timer. When it expires, the @ref NETAPI_TIMER_CB_T
+ * will be called.
+ * @param[in] @ref NATAPI_TIMER_GROUP_HANDLE_T : the handle to the timer group
+ * @param[in] @ref NATAPI_TIMER_T : the handle to the individual timer to cancel
+ * @param[in] int* : pointer to error return
+ * @retval none
+ * @pre @ref netapi_TimerGroupStartTimer
+ */
+//Cancel a timer
+void netapi_TimerGroupCancel(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ NETAPI_TIMER_T timerId,
+ int *pErr);
+
+//close an opened timer group
+void netapi_TimerGroupClose(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ int *pErr);
+
+//close an opened timer group
+void netapi_TimerGroupDelete(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ int *pErr);
+
+//extract netapi handle from timer group handle
+NETAPI_T netap_TimerGroupGetNH( NETAPI_TIMER_GROUP_HANDLE_T th);
+
+//poll a specific timer group
+int netapi_TimerGroupPoll(NETAPI_TIMER_GROUP_HANDLE_T th, int maxTimers);
+
+/*
+* @brief API for Polling all timer groups attached to an instance
+ *
+ * @details this function is used to poll all or a specified subset of the timer groups of an
+ * instance. A mask can be set to filter which categories of timer groups (local vs global etc)
+ * to poll. The approximate max # of timers to process can also be set.
+ * @param[in] @ref NATAPI_T : the handle of the netapi instance.
+ * @param[in] @ref NATAPI_TIMER_FILTER_T : the bit mask of timer group types to poll
+ * @param[in] int : approximate max number of timers to process. NOTE: this can be used to
+ * coarsely control how many timers to process. In general, all timers that have been
+ * hashed into the same cell and have expired will be processed regardless of the
+ * maxTmers setting.. [FUTURE]
+ * @retval none
+ * @pre @ref netapi_init, @ref netapi_TimerGroupCreate
+ */
+
+//poll all timers
+int netapi_TimerGroupPollAll(NETAPI_T nh, NETAPI_TIMER_FILTER_T f, int maxTimers);
+
+/*****************END API*********************************/
+
+
+#endif
index d6e133bb64b8daa5c051d2633ddb476d42e5969c..d02ef127ad2879731e9cb75424866e64b2405e54 100755 (executable)
//(7) # of QM descriptors (total)
// this can be set set in netapi_init
// MUST BE POWER OF 2
-#define TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM 1024 /* 16384 is abs max */
+#define TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM 2048 /* 16384 is abs max */
//(8) Region info
#define TUNE_NETAPI_NUM_LOCAL_DESC 64
/* at least as big as DEFAULT_NUM_SOLO+DEFAULT_NUM_BUFFERS but also a power of 2*/
-#define TUNE_NETAPI_NUM_GLOBAL_DESC 512
+#define TUNE_NETAPI_NUM_GLOBAL_DESC 1024
#define TUNE_NETAPI_DESC_SIZE 128 //don't change!!
#ifdef NETAPI_USE_DDR
//(10) NWAL (internal) config. Should not have to change
-#define TUNE_NETAPI_CONFIG_MAX_PA_TO_SA_DESC 16
-#define TUNE_NETAPI_CONFIG_MAX_SA_TO_PA_DESC 16
+#define TUNE_NETAPI_CONFIG_MAX_PA_TO_SA_DESC 32
+#define TUNE_NETAPI_CONFIG_MAX_SA_TO_PA_DESC 32
#define TUNE_NETAPI_MAX_NUM_MAC 2 //2 'logical' mac addresses
-#define TUNE_NETAPI_MAX_NUM_IP 4 //2 ip addresses
+#define TUNE_NETAPI_MAX_NUM_IP 32 //2 ip addresses
#define TUNE_NETAPI_MAX_NUM_PORTS_PER_CORE 4 //udp/tcp ports -> for lUT2 )
#define TUNE_NETAPI_MAX_NUM_PORTS (TUNE_NETAPI_MAX_NUM_PORTS_PER_CORE * (TUNE_NETAPI_NUM_CORES))
#ifdef NETAPI_ENABLE_SECURITY
-#define TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS 4
+#define TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS 32
#else
#define TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS 0
#endif
index f316d0656e1eab4407237d2e3f67aeea67077c33..8ab74729a00509ced215ba91b71c5adc488a522f 100755 (executable)
-/*********************************************\r
- * File: netsync.h\r
- * Purpose: NETAPI Synchronization primitives\r
- **************************************************************\r
- * FILE: netsync.h\r
- * \r
- * DESCRIPTION: netapi synch utilities header file for user space transport\r
- * library\r
- * \r
- * REVISION HISTORY: rev 0.0.1 \r
- *\r
- * Copyright (c) Texas Instruments Incorporated 2010-2011\r
- * \r
- * Redistribution and use in source and binary forms, with or without \r
- * modification, are permitted provided that the following conditions \r
- * are met:\r
- *\r
- * Redistributions of source code must retain the above copyright \r
- * notice, this list of conditions and the following disclaimer.\r
- *\r
- * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the \r
- * documentation and/or other materials provided with the \r
- * distribution.\r
- *\r
- * Neither the name of Texas Instruments Incorporated nor the names of\r
- * its contributors may be used to endorse or promote products derived\r
- * from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-\r
- **********************************************/\r
-#ifndef NETAPI_SYNC_H\r
-#define NETAPI_SYNCH_H\r
-\r
-/*--------------------------*/\r
-/*----------spinlock--------*/\r
-/*--------------------------*/\r
-\r
-typedef int NETAPI_SPINLOCK_T;\r
-\r
-#define NETAPI_SPINLOCK_LOCKVAL 1\r
-#define NETAPI_SPINLOCK_UNLOCKVAL 0 //never change!!\r
-#define NETAPI_SPINLOCK_UNLOCKED_INITIALIZER (NETAPI_SPINLOCK_UNLOCKVAL)\r
-\r
-/* init a lock */\r
-static inline void netapi_spinlock_init (NETAPI_SPINLOCK_T * val) {*val=NETAPI_SPINLOCK_UNLOCKVAL;}\r
-\r
-/* lock a spinlock */\r
-static inline void netapi_spinlock_lock(NETAPI_SPINLOCK_T * val)\r
-{\r
-while(__sync_lock_test_and_set(val, NETAPI_SPINLOCK_LOCKVAL))\r
- {\r
- asm volatile("nop" :: );\r
- asm volatile("nop" :: );\r
- asm volatile("nop" :: );\r
- asm volatile("nop" :: );\r
- }\r
-}\r
-\r
-/* try to get lock 1 time. Return 1 if ok, 0 if un-successful */\r
-static inline int netapi_spinlock_try_lock( NETAPI_SPINLOCK_T* val)\r
-{\r
- int i=0;\r
- if (__sync_lock_test_and_set(val, NETAPI_SPINLOCK_LOCKVAL)) return 0;\r
- return 1;\r
-}\r
-\r
-\r
-/* unlock a spinlock. */\r
-static inline void netapi_spinlock_unlock(NETAPI_SPINLOCK_T * val)\r
-{\r
- __sync_lock_release(val);\r
-}\r
-\r
-/* poll a lock, return 0 if unlocked, NETAPI_SPINLOCK_LOCKVAL if locked */\r
-static inline int netapi_spinlock_is_locked(NETAPI_SPINLOCK_T * val)\r
-{\r
- return *val;\r
-}\r
-\r
-/*--------------------------*/\r
-/*----------rwlock--------*/\r
-/*--------------------------*/\r
-\r
-/* a rw lock strucuture */\r
-typedef struct RWLOCK_Tag\r
-{\r
- NETAPI_SPINLOCK_T lock_outer; //lock this structure. very short duration lock\r
- NETAPI_SPINLOCK_T lock_w; //real write lock\r
- unsigned long n_readers; /* # readers active */\r
-} NETAPI_RWLOCK_T;\r
-\r
-//initialize a rw lock \r
-static inline void netapi_rwlock_init(NETAPI_RWLOCK_T * p_lock)\r
-{\r
- netapi_spinlock_init(&p_lock->lock_outer);\r
- netapi_spinlock_init(&p_lock->lock_w);\r
- p_lock->n_readers=0;\r
-}\r
-\r
-// lock a write lock. \r
-static inline void netapi_rwlock_write_lock(NETAPI_RWLOCK_T * p_lock)\r
-{\r
- int ret;\r
- while(1)\r
- {\r
- netapi_spinlock_lock(&p_lock->lock_outer); //get outer lock - now nothing can change\r
- // check for 0 readers\r
- if(p_lock->n_readers)\r
- {\r
- netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer & spin\r
- asm volatile("nop" :: );\r
- asm volatile("nop" :: );\r
- asm volatile("nop" :: );\r
- asm volatile("nop" :: );\r
- continue;\r
- }\r
-\r
- //ok, no readers. see if we can get writer lock\r
- ret=netapi_spinlock_try_lock(&p_lock->lock_w); //try get writer lock 1 time\r
- if(!ret) \r
- {\r
- netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer & spin\r
- asm volatile("nop" :: );\r
- asm volatile("nop" :: );\r
- asm volatile("nop" :: );\r
- asm volatile("nop" :: );\r
- continue; /* try again */\r
- }\r
- netapi_spinlock_unlock(&p_lock->lock_outer); //got write lock=> no other writer, no readers! Keep the writelock but unlock the outer.\r
- return;\r
- }\r
-}\r
-\r
-//unlock a writer part of rwlock */\r
-static inline void netapi_rwlock_write_unlock(NETAPI_RWLOCK_T * p_lock)\r
-{\r
- netapi_spinlock_unlock(&p_lock->lock_w);\r
-}\r
-\r
-//grab a read lock\r
-//=> can be other readers, but no writer\r
-static inline void netapi_rwlock_read_lock(NETAPI_RWLOCK_T * p_lock)\r
-{\r
-int ret;\r
-\r
-while(1)\r
-{\r
- /*1st grab outer lock. once we have it, nothing can change */\r
- netapi_spinlock_lock(&p_lock->lock_outer);\r
-\r
- /* see if there is a writer */\r
- ret= netapi_spinlock_is_locked(&p_lock->lock_w);\r
-\r
- //there is a writer\r
- if (ret)\r
- {\r
- netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer and spin\r
- asm volatile("nop" :: );\r
- asm volatile("nop" :: );\r
- asm volatile("nop" :: );\r
- asm volatile("nop" :: );\r
- continue; \r
- }\r
-\r
- /* there is no writer so we can read!*/\r
- p_lock->n_readers+=1;\r
-\r
- /* mb ? */\r
- __sync_synchronize(); //make sure every core sees that n_readers has changed\r
-\r
- /* now give back the outer lock */\r
- netapi_spinlock_unlock(&p_lock->lock_outer);\r
- return;\r
-}\r
-}\r
-\r
-//rw_lock reader unlock\r
-static inline void netapi_rwlock_read_unlock(NETAPI_RWLOCK_T * p_lock)\r
-{\r
- //grab outer\r
- netapi_spinlock_lock(&p_lock->lock_outer);\r
-\r
- //decrement # of readers. Make sure all cores see update\r
- p_lock->n_readers--;\r
- __sync_synchronize(); \r
- //TBD: need to check for <0? \r
- \r
- /* give up the outer */\r
- netapi_spinlock_unlock(&p_lock->lock_outer);\r
-}\r
-\r
-/*--------------------------*/\r
-/*----------atomic32--------*/\r
-/*--------------------------*/\r
-typedef struct NETAPI_ATOMIC32_tag\r
-{\r
- long val;\r
-} NETAPI_ATOMIC32_T;\r
-\r
-#define NETAPI_ATOMIC_INIT32(x) {x}\r
-static inline int netapi_atomic_read32(NETAPI_ATOMIC32_T *p) {return p->val;}\r
-\r
-static inline void netapi_atomic_set32(NETAPI_ATOMIC32_T *p, int val) \r
-{__sync_fetch_and_add(&p->val,0); } //todo crude, why not p->val=val?\r
-\r
-static inline void netapi_atomic_add32(NETAPI_ATOMIC32_T *p, int val)\r
-{__sync_fetch_and_add(&p->val,val);}\r
-\r
-static inline void netapi_atomic_sub32(NETAPI_ATOMIC32_T *p, int val)\r
-{__sync_fetch_and_sub(&p->val,val);}\r
-\r
-#define NETAPI_atomic_inc32(p) netapi_atomic_add32(p,1);\r
-#define NETAPI_atomic_dec32(p) netapi_atomic_sub32(p,1);\r
-\r
-static inline int netapi_atomic_add_return32(NETAPI_ATOMIC32_T *p, int val)\r
-{return __sync_add_and_fetch(&p->val,val);}\r
-\r
-static inline int netapi_atomic_sub_return32(NETAPI_ATOMIC32_T *p, int val)\r
-{return __sync_sub_and_fetch(&p->val,val);}\r
-\r
-static inline int netapi_atomic_inc_and_test32(NETAPI_ATOMIC32_T *p)\r
-{return __sync_add_and_fetch(&p->val,1);}\r
-\r
-static inline int netapi_atomic_dec_and_test32(NETAPI_ATOMIC32_T *p)\r
-{return !__sync_sub_and_fetch(&p->val,1);}\r
-\r
-static inline int netapi_atomic_test_and_set32(NETAPI_ATOMIC32_T *p)\r
-{return (! _sync_lock_test_and_set(p, 1));}\r
-\r
-#define netapi_atomic_clear32(p) netapi_atomic_set32(p,0);\r
-\r
-/*--------------------------*/\r
-/*----------atomic64--------*/\r
-/*--------------------------*/\r
-typedef struct NETAPI_ATOMIC64_Tag\r
-{\r
- NETAPI_SPINLOCK_T lock;\r
- long long val;\r
-} NETAPI_ATOMIC64_T;\r
-\r
-#define NETAPI_ATOMIC_INIT64(x) {NETAPI_SPINLOCK_UNLOCKED_INITIALIZER,x}\r
-\r
-static inline long long netapi_atomic_read64(NETAPI_ATOMIC64_T *p)\r
-{\r
-long long latch_val;\r
-netapi_spinlock_lock(&p->lock); //acquire lock\r
-latch_val = p->val;\r
-netapi_spinlock_unlock(&p->lock); //free lock\r
-return latch_val;\r
-}\r
-\r
-static inline void netapi_atomic_set64(NETAPI_ATOMIC64_T *p,long long val)\r
-{\r
-netapi_spinlock_lock(&p->lock); //acquire lock\r
-p->val = val;\r
-//__sync_synchronize(); //todo: may not need as unlock will do this also probably\r
-netapi_spinlock_unlock(&p->lock); //free lock\r
-}\r
-\r
-static inline void netapi_atomic_add64(NETAPI_ATOMIC64_T *p, long long val) \r
-{\r
-netapi_spinlock_lock(&p->lock); //acquire lock\r
-p->val += val;\r
-//__sync_synchronize(); //todo: may not need as unlock will do this also probably\r
-netapi_spinlock_unlock(&p->lock); //free lock\r
-}\r
-\r
-/*******************************************************\r
- ****************memory barrier************************\r
-******************************************************/\r
-static inline void netapi_mb(){__sync_synchronize();}\r
-static inline void netapi_rmb(){__sync_synchronize();}\r
-static inline void netapi_wmb(){__sync_synchronize();}\r
-\r
-\r
-#endif\r
+/*********************************************
+ * File: netsync.h
+ * Purpose: NETAPI Synchronization primitives
+ **************************************************************
+ * FILE: netsync.h
+ *
+ * DESCRIPTION: netapi synch utilities 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 NETAPI_SYNC_H
+#define NETAPI_SYNCH_H
+
+/*--------------------------*/
+/*----------spinlock--------*/
+/*--------------------------*/
+
+typedef int NETAPI_SPINLOCK_T;
+
+#define NETAPI_SPINLOCK_LOCKVAL 1
+#define NETAPI_SPINLOCK_UNLOCKVAL 0 //never change!!
+#define NETAPI_SPINLOCK_UNLOCKED_INITIALIZER (NETAPI_SPINLOCK_UNLOCKVAL)
+
+/* init a lock */
+static inline void netapi_spinlock_init (NETAPI_SPINLOCK_T * val) {*val=NETAPI_SPINLOCK_UNLOCKVAL;}
+
+/* lock a spinlock */
+static inline void netapi_spinlock_lock(NETAPI_SPINLOCK_T * val)
+{
+while(__sync_lock_test_and_set(val, NETAPI_SPINLOCK_LOCKVAL))
+ {
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ }
+}
+
+/* try to get lock 1 time. Return 1 if ok, 0 if un-successful */
+static inline int netapi_spinlock_try_lock( NETAPI_SPINLOCK_T* val)
+{
+ int i=0;
+ if (__sync_lock_test_and_set(val, NETAPI_SPINLOCK_LOCKVAL)) return 0;
+ return 1;
+}
+
+
+/* unlock a spinlock. */
+static inline void netapi_spinlock_unlock(NETAPI_SPINLOCK_T * val)
+{
+ __sync_lock_release(val);
+}
+
+/* poll a lock, return 0 if unlocked, NETAPI_SPINLOCK_LOCKVAL if locked */
+static inline int netapi_spinlock_is_locked(NETAPI_SPINLOCK_T * val)
+{
+ return *val;
+}
+
+/*--------------------------*/
+/*----------rwlock--------*/
+/*--------------------------*/
+
+/* a rw lock strucuture */
+typedef struct RWLOCK_Tag
+{
+ NETAPI_SPINLOCK_T lock_outer; //lock this structure. very short duration lock
+ NETAPI_SPINLOCK_T lock_w; //real write lock
+ unsigned long n_readers; /* # readers active */
+} NETAPI_RWLOCK_T;
+
+//initialize a rw lock
+static inline void netapi_rwlock_init(NETAPI_RWLOCK_T * p_lock)
+{
+ netapi_spinlock_init(&p_lock->lock_outer);
+ netapi_spinlock_init(&p_lock->lock_w);
+ p_lock->n_readers=0;
+}
+
+// lock a write lock.
+static inline void netapi_rwlock_write_lock(NETAPI_RWLOCK_T * p_lock)
+{
+ int ret;
+ while(1)
+ {
+ netapi_spinlock_lock(&p_lock->lock_outer); //get outer lock - now nothing can change
+ // check for 0 readers
+ if(p_lock->n_readers)
+ {
+ netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer & spin
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ continue;
+ }
+
+ //ok, no readers. see if we can get writer lock
+ ret=netapi_spinlock_try_lock(&p_lock->lock_w); //try get writer lock 1 time
+ if(!ret)
+ {
+ netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer & spin
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ continue; /* try again */
+ }
+ netapi_spinlock_unlock(&p_lock->lock_outer); //got write lock=> no other writer, no readers! Keep the writelock but unlock the outer.
+ return;
+ }
+}
+
+//unlock a writer part of rwlock */
+static inline void netapi_rwlock_write_unlock(NETAPI_RWLOCK_T * p_lock)
+{
+ netapi_spinlock_unlock(&p_lock->lock_w);
+}
+
+//grab a read lock
+//=> can be other readers, but no writer
+static inline void netapi_rwlock_read_lock(NETAPI_RWLOCK_T * p_lock)
+{
+int ret;
+
+while(1)
+{
+ /*1st grab outer lock. once we have it, nothing can change */
+ netapi_spinlock_lock(&p_lock->lock_outer);
+
+ /* see if there is a writer */
+ ret= netapi_spinlock_is_locked(&p_lock->lock_w);
+
+ //there is a writer
+ if (ret)
+ {
+ netapi_spinlock_unlock(&p_lock->lock_outer); //give up outer and spin
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ asm volatile("nop" :: );
+ continue;
+ }
+
+ /* there is no writer so we can read!*/
+ p_lock->n_readers+=1;
+
+ /* mb ? */
+ __sync_synchronize(); //make sure every core sees that n_readers has changed
+
+ /* now give back the outer lock */
+ netapi_spinlock_unlock(&p_lock->lock_outer);
+ return;
+}
+}
+
+//rw_lock reader unlock
+static inline void netapi_rwlock_read_unlock(NETAPI_RWLOCK_T * p_lock)
+{
+ //grab outer
+ netapi_spinlock_lock(&p_lock->lock_outer);
+
+ //decrement # of readers. Make sure all cores see update
+ p_lock->n_readers--;
+ __sync_synchronize();
+ //TBD: need to check for <0?
+
+ /* give up the outer */
+ netapi_spinlock_unlock(&p_lock->lock_outer);
+}
+
+/*--------------------------*/
+/*----------atomic32--------*/
+/*--------------------------*/
+typedef struct NETAPI_ATOMIC32_tag
+{
+ long val;
+} NETAPI_ATOMIC32_T;
+
+#define NETAPI_ATOMIC_INIT32(x) {x}
+static inline int netapi_atomic_read32(NETAPI_ATOMIC32_T *p) {return p->val;}
+
+static inline void netapi_atomic_set32(NETAPI_ATOMIC32_T *p, int val)
+{__sync_fetch_and_add(&p->val,0); } //todo crude, why not p->val=val?
+
+static inline void netapi_atomic_add32(NETAPI_ATOMIC32_T *p, int val)
+{__sync_fetch_and_add(&p->val,val);}
+
+static inline void netapi_atomic_sub32(NETAPI_ATOMIC32_T *p, int val)
+{__sync_fetch_and_sub(&p->val,val);}
+
+#define NETAPI_atomic_inc32(p) netapi_atomic_add32(p,1);
+#define NETAPI_atomic_dec32(p) netapi_atomic_sub32(p,1);
+
+static inline int netapi_atomic_add_return32(NETAPI_ATOMIC32_T *p, int val)
+{return __sync_add_and_fetch(&p->val,val);}
+
+static inline int netapi_atomic_sub_return32(NETAPI_ATOMIC32_T *p, int val)
+{return __sync_sub_and_fetch(&p->val,val);}
+
+static inline int netapi_atomic_inc_and_test32(NETAPI_ATOMIC32_T *p)
+{return __sync_add_and_fetch(&p->val,1);}
+
+static inline int netapi_atomic_dec_and_test32(NETAPI_ATOMIC32_T *p)
+{return !__sync_sub_and_fetch(&p->val,1);}
+
+static inline int netapi_atomic_test_and_set32(NETAPI_ATOMIC32_T *p)
+{return (! _sync_lock_test_and_set(p, 1));}
+
+#define netapi_atomic_clear32(p) netapi_atomic_set32(p,0);
+
+/*--------------------------*/
+/*----------atomic64--------*/
+/*--------------------------*/
+typedef struct NETAPI_ATOMIC64_Tag
+{
+ NETAPI_SPINLOCK_T lock;
+ long long val;
+} NETAPI_ATOMIC64_T;
+
+#define NETAPI_ATOMIC_INIT64(x) {NETAPI_SPINLOCK_UNLOCKED_INITIALIZER,x}
+
+static inline long long netapi_atomic_read64(NETAPI_ATOMIC64_T *p)
+{
+long long latch_val;
+netapi_spinlock_lock(&p->lock); //acquire lock
+latch_val = p->val;
+netapi_spinlock_unlock(&p->lock); //free lock
+return latch_val;
+}
+
+static inline void netapi_atomic_set64(NETAPI_ATOMIC64_T *p,long long val)
+{
+netapi_spinlock_lock(&p->lock); //acquire lock
+p->val = val;
+//__sync_synchronize(); //todo: may not need as unlock will do this also probably
+netapi_spinlock_unlock(&p->lock); //free lock
+}
+
+static inline void netapi_atomic_add64(NETAPI_ATOMIC64_T *p, long long val)
+{
+netapi_spinlock_lock(&p->lock); //acquire lock
+p->val += val;
+//__sync_synchronize(); //todo: may not need as unlock will do this also probably
+netapi_spinlock_unlock(&p->lock); //free lock
+}
+
+/*******************************************************
+ ****************memory barrier************************
+******************************************************/
+static inline void netapi_mb(){__sync_synchronize();}
+static inline void netapi_rmb(){__sync_synchronize();}
+static inline void netapi_wmb(){__sync_synchronize();}
+
+
+#endif
index 48b6966f622d0cb844e21f0857cf1f845b63f010..bc1d87472cb46fb98f6caeb1767cfb7957630ce0 100755 (executable)
PKTIO_POLL_T * p_poll_cfg, //polling configuration
int * err)
{
- handle->_poll((struct PKTIO_HANDLE_tag *) handle, p_poll_cfg, err);
+ return handle->_poll((struct PKTIO_HANDLE_tag *) handle, p_poll_cfg, err);
}
/*
index ef1a0f9c4c5549b4ac956851ce7474810f9178c8..ffe4fc89c15aabfbebc8f01b54910a8f5800e378 100755 (executable)
#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1 128
uint8_t paBuf1[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF1]ALIGN(CACHE_LINESZ);
-#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2 768
+//#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2 768
+#define NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2 6144
uint8_t paBuf2[NETAPI_NWAL_CONFIG_BUFSIZE_PA_BUF2]ALIGN(CACHE_LINESZ);
/* Memory used for SA LLD global Handle */
index 5c5f85bb690a071738eb6e90b30e6c603cc9b2e9..1b5ea732334176c8b7d11e42b3534ef8458a14fb 100755 (executable)
-/****************************************\r
- * File: netapi_sched.c\r
- * Purpose: netapi scheduling module\r
- * NOTE: This sample right now.\r
- **************************************************************\r
- * FILE: netapi_sched.c\r
- * \r
- * DESCRIPTION: netapi sample scheduler source file for user space transport\r
- * library\r
- * \r
- * REVISION HISTORY: rev 0.0.1 \r
- *\r
- * Copyright (c) Texas Instruments Incorporated 2010-2011\r
- * \r
- * Redistribution and use in source and binary forms, with or without \r
- * modification, are permitted provided that the following conditions \r
- * are met:\r
- *\r
- * Redistributions of source code must retain the above copyright \r
- * notice, this list of conditions and the following disclaimer.\r
- *\r
- * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the \r
- * documentation and/or other materials provided with the \r
- * distribution.\r
- *\r
- * Neither the name of Texas Instruments Incorporated nor the names of\r
- * its contributors may be used to endorse or promote products derived\r
- * from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-\r
- ****************************************/\r
-\r
-#include "netapi.h"\r
-#include "netapi_sched.h"\r
-\r
-\r
-/****************************************/\r
-/************API************************/\r
-/**************************************/\r
-\r
-/* open a scheduling contex */\r
-NETAPI_SCHED_HANDLE_T * netapi_schedOpen(NETAPI_T n, NETAPI_SCHED_CONFIG_T * p_config, int *p_err)\r
-{\r
- *p_err=0;\r
- NETAPI_SCHED_HANDLE_T * ph = (NETAPI_SCHED_HANDLE_T *) netapi_get_scheduler(n);\r
- if(!ph) {*p_err= NETAPI_ERR_NOMEM; return NULL;}\r
- if(!p_config) {*p_err= NETAPI_ERR_BAD_INPUT; return NULL;}\r
- memcpy(&ph->config,p_config,sizeof(NETAPI_SCHED_CONFIG_T));\r
- ph->start = netapi_getTimestamp();\r
- ph->back = (void *) n;\r
- if (ph->config.valid_flags & NETAPI_SCHED_DURATION)\r
- {\r
- if (ph->config.duration == NETAPI_SCHED_FOREVER) \r
- {\r
- ph->shutdown_time=(uint64_t) -1; \r
- }\r
- else\r
- {\r
- ph->shutdown_time = ph->start + ph->config.duration;\r
- }\r
- }\r
- else ph->shutdown_time = (uint64_t) -1;\r
- ph->state =NETAPI_SCHED_STATE_ACTIVE; \r
- return(ph);\r
-\r
-}\r
-\r
-/* re-configure a scheduling context */\r
-int netapi_schedControl(NETAPI_SCHED_HANDLE_T *s, NETAPI_SCHED_CONFIG_T *p_config, int *p_err)\r
-{\r
- /* not implemented */\r
-\r
- return 0;\r
-}\r
-\r
-\r
-/* main entry point. caller gives up control to scheduler */\r
-int netapi_schedWaitForEvents(NETAPI_SCHED_HANDLE_T *s, int *p_err)\r
-{\r
- int err;\r
- *p_err=0;\r
- unsigned long long t = netapi_getTimestamp();\r
- int next_house;\r
-\r
- next_house = s->config.interval;\r
- /* loop for duration or until shutdown */\r
- for(;t< s->shutdown_time;)\r
- {\r
- t = netapi_getTimestamp();\r
- next_house -=1;\r
- //poll all pktio channels we have open in RX mode \r
- pktio_pollAll((NETAPI_T) s->back, NULL, &err);\r
-\r
- //poll pktlib garbage collections for registered heaps..\r
- netapi_pollHeapGarbage((NETAPI_T) s->back);\r
- \r
- //todo timers (local and global)\r
- netapi_TimerGroupPollAll((NETAPI_T) s->back, NETAPI_TIMER_FITLER_ALL, 100000);\r
-\r
- //poll NETCP/PA control channels \r
- netapi_netcpPoll((NETAPI_T) s->back);\r
-\r
- //see if time to do a house keeping callback\r
- if ((s->config.valid_flags & NETAPI_SCHED_CBV) && s->config.house_cb)\r
- if (next_house<=0)\r
- {\r
- s->config.house_cb(s);\r
- next_house = s->config.interval;\r
- }\r
- //see if we were closed and/or its time to close\r
- if (s->state!= NETAPI_SCHED_STATE_ACTIVE) \r
- { s->state=NETAPI_SCHED_STATE_SHUT; break;}\r
- }\r
- return 1;\r
-}\r
-\r
-/* shutdown scheduler context */\r
-int netapi_schedShutdown(NETAPI_SCHED_HANDLE_T * s, NETAPI_SCHED_SHUTDOWN_T * p_close, int * p_err)\r
-{\r
- *p_err=0;\r
- s->state=NETAPI_SCHED_STATE_SHUTTING; //say we are closing\r
-\r
- return 1;\r
-}\r
-\r
-\r
+/****************************************
+ * File: netapi_sched.c
+ * Purpose: netapi scheduling module
+ * NOTE: This sample right now.
+ **************************************************************
+ * FILE: netapi_sched.c
+ *
+ * DESCRIPTION: netapi sample scheduler 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 "netapi.h"
+#include "netapi_sched.h"
+
+#define NO_TIMER //turn off timer related scheduling
+#define NO_GARBAGE //turn off garbage collection
+
+volatile unsigned long long netapi_sched_num_pkts=0L;
+volatile unsigned long long netapi_sched_busy_cycles=0L;
+volatile unsigned long long netapi_sched_cache_cycles=0L;
+void netapi_sched_get_stats(unsigned long long * p_pkts, unsigned long long * p_cycles,
+ unsigned long long * p_cache_cycles)
+{
+ *p_pkts= netapi_sched_num_pkts;
+ *p_cycles= netapi_sched_busy_cycles;
+ *p_cache_cycles= netapi_sched_cache_cycles;
+ return;
+}
+/****************************************/
+/************API************************/
+/**************************************/
+
+/* open a scheduling contex */
+NETAPI_SCHED_HANDLE_T * netapi_schedOpen(NETAPI_T n, NETAPI_SCHED_CONFIG_T * p_config, int *p_err)
+{
+ *p_err=0;
+ NETAPI_SCHED_HANDLE_T * ph = (NETAPI_SCHED_HANDLE_T *) netapi_get_scheduler(n);
+ if(!ph) {*p_err= NETAPI_ERR_NOMEM; return NULL;}
+ if(!p_config) {*p_err= NETAPI_ERR_BAD_INPUT; return NULL;}
+ memcpy(&ph->config,p_config,sizeof(NETAPI_SCHED_CONFIG_T));
+ ph->start = netapi_getTimestamp();
+ ph->back = (void *) n;
+ if (ph->config.valid_flags & NETAPI_SCHED_DURATION)
+ {
+ if (ph->config.duration == NETAPI_SCHED_FOREVER)
+ {
+ ph->shutdown_time=(uint64_t) -1;
+ }
+ else
+ {
+ ph->shutdown_time = ph->start + ph->config.duration;
+ }
+ }
+ else ph->shutdown_time = (uint64_t) -1;
+ ph->state =NETAPI_SCHED_STATE_ACTIVE;
+ return(ph);
+
+}
+
+/* re-configure a scheduling context */
+int netapi_schedControl(NETAPI_SCHED_HANDLE_T *s, NETAPI_SCHED_CONFIG_T *p_config, int *p_err)
+{
+ /* not implemented */
+
+ return 0;
+}
+
+
+/* main entry point. caller gives up control to scheduler */
+int netapi_schedWaitForEvents(NETAPI_SCHED_HANDLE_T *s, int *p_err)
+{
+ int err;
+ *p_err=0;
+ unsigned long long t = netapi_getTimestamp();
+ int next_house;
+ volatile int pkts;
+ volatile unsigned long t1;
+ volatile unsigned long t2;
+ volatile unsigned int cache_op_b2;
+ volatile int n_c_ops;
+
+ next_house = s->config.interval;
+ /* loop for duration or until shutdown */
+ for(;t< s->shutdown_time;)
+ {
+#ifndef NO_TIMER
+ t = netapi_getTimestamp();
+#endif
+ next_house -=1;
+ //poll all pktio channels we have open in RX mode
+ Osal_cache_op_measure_reset();
+ t1=netapi_timing_start();
+ pkts=pktio_pollAll((NETAPI_T) s->back, NULL, &err);
+ t2=netapi_timing_start();
+ if (pkts)
+ {
+ netapi_sched_num_pkts+= (unsigned long long) pkts;
+ netapi_sched_busy_cycles += (unsigned long long) (t2-t1);
+ cache_op_b2= Osal_cache_op_measure(&n_c_ops);
+ netapi_sched_cache_cycles += (unsigned long long) cache_op_b2;
+ }
+
+#ifndef NO_GARBAGE
+ //poll pktlib garbage collections for registered heaps..
+ netapi_pollHeapGarbage((NETAPI_T) s->back);
+#endif
+
+#ifndef NO_TIMER
+ //todo timers (local and global)
+ netapi_TimerGroupPollAll((NETAPI_T) s->back, NETAPI_TIMER_FITLER_ALL, 100000);
+#endif
+ //poll NETCP/PA control channels
+ netapi_netcpPoll((NETAPI_T) s->back);
+
+ //see if time to do a house keeping callback
+ if ((s->config.valid_flags & NETAPI_SCHED_CBV) && s->config.house_cb)
+ if (next_house<=0)
+ {
+ s->config.house_cb(s);
+ next_house = s->config.interval;
+ }
+ //see if we were closed and/or its time to close
+ if (s->state!= NETAPI_SCHED_STATE_ACTIVE)
+ { s->state=NETAPI_SCHED_STATE_SHUT; break;}
+ }
+ return 1;
+}
+
+/* shutdown scheduler context */
+int netapi_schedShutdown(NETAPI_SCHED_HANDLE_T * s, NETAPI_SCHED_SHUTDOWN_T * p_close, int * p_err)
+{
+ *p_err=0;
+ s->state=NETAPI_SCHED_STATE_SHUTTING; //say we are closing
+
+ return 1;
+}
+
+
dmSaParam.dmSaParam.aadSize=0; /**todo: pass in or deduce */
dmSaParam.dmSaParam.enc1st = (sa_info->dir ==NWAL_SA_DIR_OUTBOUND) ? nwal_TRUE : nwal_FALSE; //encypt 1st for outbound
//todo; allow app q for Sideband return
- dmSaParam.dmSaParam.appRxPktFlowId= CPPI_PARAM_NOT_SPECIFIED;
- dmSaParam.dmSaParam.appRxPktQueue= CPPI_PARAM_NOT_SPECIFIED;
memcpy(&dmSaParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
retValue = nwal_setDMSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
(nwal_AppId)appId,
+void netapi_getSaStats (NETAPI_T h, NETCP_CFG_SA_T handle,
+ NETAPI_SA_STATS_T* pSaStats)
+{
+ NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
+void * handle_inflow;
+void * handle_sideband;
+int tunnelId = (handle >>8) &0xffff;
+int have_to_wait = 1;
+ handle_inflow = netcp_cfgp_get_sa_handles(&netapi_get_global()->nwal_context,
+ tunnelId, &handle_sideband);
+ if(handle_inflow)
+ {
+ //printf("netapi_getSaStats(): handle inflow valid\n");
+ nwal_getSecAssocStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
+ handle_inflow, &(pSaStats->saIpsecStats));
+ pSaStats->mode_active |= NETAPI_INFLOW_MODE_ACTIVE;
+ }
+ if(handle_sideband)
+ {
+ //printf("netapi_getSaStats(): handle sideband valid\n");
+ nwal_getDataModeStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
+ handle_sideband, &(pSaStats->dataModeStats));
+ pSaStats->mode_active |= NETAPI_SIDEBAND_MODE_ACTIVE;
+ }
+
+}
index 3cf1abe3e61a778f6edb0c8dcc48cb4eb3f24199..34b118e95d69055d7a04c2a89d436cc2ac19febd 100755 (executable)
-/*******************************\r
- * FILE: netapi_timer.c\r
- * Purpose: implementation of user space timers \r
- **************************************************************\r
- * FILE: netapi.c\r
- * \r
- * DESCRIPTION: user space timers main source file for user space transport\r
- * library\r
- * \r
- * REVISION HISTORY: rev 0.0.1 \r
- *\r
- * Copyright (c) Texas Instruments Incorporated 2010-2011\r
- * \r
- * Redistribution and use in source and binary forms, with or without \r
- * modification, are permitted provided that the following conditions \r
- * are met:\r
- *\r
- * Redistributions of source code must retain the above copyright \r
- * notice, this list of conditions and the following disclaimer.\r
- *\r
- * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the \r
- * documentation and/or other materials provided with the \r
- * distribution.\r
- *\r
- * Neither the name of Texas Instruments Incorporated nor the names of\r
- * its contributors may be used to endorse or promote products derived\r
- * from this software without specific prior written permission.\r
- *\r
-*\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- *\r
- ***************************************************************/\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <unistd.h>\r
-#include <string.h>\r
-#include "netapi.h"\r
-#include "netapi_timer.h"\r
-#include "timer_loc.h"\r
-\r
-\r
-/*******************************************************************\r
- * hash function: returns cell to place timer object in\r
- * \r
- ******************************************************************/\r
-/* static */ int our_hash(\r
- unsigned long long ct,\r
- int n_cells,\r
- unsigned int cell_width)\r
-{\r
-int c;\r
- //simple hash function\r
- c= (ct/cell_width) % n_cells;\r
- return c;\r
-\r
-}\r
-\r
-//iterator on TIMER_LIST_T\r
-NETAPI_TIMER_T netapi_TimerGetFirst( NETAPI_TIMER_LIST_T list)\r
-{ return (NETAPI_TIMER_T) ((TIM_LIST_T *)list)->head; }\r
-\r
-NETAPI_TIMER_T netapi_TimerGetNext( NETAPI_TIMER_LIST_T list,NETAPI_TIMER_T prev)\r
-{return prev ? (NETAPI_TIMER_T) ((TIM_T*) prev)->next:NULL ;}\r
-\r
-//return cookie associated with timer object \r
-void * netapi_TimerGetCookie(NETAPI_TIMER_T timer)\r
-{ return ((TIM_T*) timer)->cookie; }\r
-\r
-//return timeer value associated with timer object \r
-unsigned long long netapi_TimerGetTs(NETAPI_TIMER_T timer)\r
-{ return ((TIM_T*) timer)->t; }\r
-\r
-#if 0\r
-//timer callback\r
-typedef void (*NETAPI_TIMER_CB_T) (\r
- NETAPI_TIMER_GROUP_HANDLE_T th,\r
- int n_fired, //# timers fired\r
- NETAPI_TIMER_LIST_T fired_list,\r
- uint64_t currentTime);\r
-#endif\r
-\r
-static TIMER_GROUP_T temp_g; //temp. todo: put inot netHandle\r
-\r
-//create a timer group\r
-NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupCreate(\r
- NETAPI_T netHandle,\r
- char * name,\r
- NETAPI_TIMER_CB_T cb,\r
- int local, //1 if timers local to thread\r
- int exp2cancel,//1 if expect to cancel\r
- int cell_width, //in ticks\r
- int tol, //in ticks\r
- int maxTimers,\r
- int *pErr)\r
-{\r
- int ret= tim_group_create(&temp_g, TUNE_NETAPI_NUM_TIMER_CELLS, maxTimers);\r
- if (!ret) {*pErr = NETAPI_ERR_NOMEM; return NULL;}\r
- *pErr=0;\r
- temp_g.cb = cb;\r
- temp_g.local = local;\r
- temp_g.exp2cancel= exp2cancel;\r
- temp_g.cell_width=cell_width;\r
- temp_g.tol=tol;\r
- temp_g.h = netHandle;\r
- temp_g.last_polled=(netapi_getTimestamp()/cell_width) * cell_width + (cell_width-1);\r
- printf(">timer group %s created. width = %d (ticks)\n", name, cell_width);\r
- return (NETAPI_TIMER_GROUP_HANDLE_T) &temp_g;\r
-}\r
-\r
-//open a [global] timer group\r
-NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupOpen(\r
- NETAPI_T netHandle,\r
- char * name,\r
- NETAPI_TIMER_CB_T cb,\r
- int *pErr)\r
-{\r
-printf(">timer group open not implemented \n");\r
-\r
-}\r
-\r
-//start an individual timer\r
-NETAPI_TIMER_T netapi_TimerGroupStartTimer(\r
- NETAPI_TIMER_GROUP_HANDLE_T th,\r
- void * cookie,\r
- uint64_t offs2fire, //offset in group ticks \r
- int * pErr)\r
-{\r
-TIM_T * timer_obj;\r
-unsigned long long ct= netapi_getTimestamp() + offs2fire* ((TIMER_GROUP_T*) th)->cell_width;\r
-int cell;\r
-*pErr=0;\r
-\r
-//find cell where to insert\r
-cell = our_hash(ct,((TIMER_GROUP_T*) th)->n_cells , ((TIMER_GROUP_T*) th)->cell_width);\r
-\r
-//get object and insert into this cell\r
-timer_obj =tim_set(\r
- &((TIMER_GROUP_T*) th)->cells[cell],\r
- &((TIMER_GROUP_T*) th)->free , \r
- ct,\r
- cookie,\r
- pErr);\r
-if (!timer_obj) {return NULL;}\r
-//DEBUGprintf(">timer: setting timer %x for %lld ticks -> hased to cell %d\n",cookie, ct,cell);\r
-return (NETAPI_TIMER_T) timer_obj;\r
-}\r
-\r
-//Cancel a timer\r
-void netapi_TimerGroupCancel(\r
- NETAPI_TIMER_GROUP_HANDLE_T th,\r
- NETAPI_TIMER_T timerId,\r
- int *pErr)\r
-{\r
- tim_cancel((TIM_T *) timerId, pErr);\r
-}\r
-\r
-//close an opened timer group\r
-void netapi_TimerGroupClose(\r
- NETAPI_TIMER_GROUP_HANDLE_T th,\r
- int *pErr){}\r
-\r
-//delete atimer group\r
-void netapi_TimerGroupDelete(\r
- NETAPI_TIMER_GROUP_HANDLE_T th,\r
- int *pErr) {printf(">timer group delete not implemented\n");}\r
-\r
-//extract netapi handle from timer group handle\r
-NETAPI_T netap_TimerGroupGetNH( NETAPI_TIMER_GROUP_HANDLE_T th) { return ((TIMER_GROUP_T*) th)->h; }\r
-\r
-\r
-//-----for timer debuggingi-------\r
-struct\r
-{\r
-//last poll stats\r
-int n_tot;\r
-int c_seen;\r
-\r
-int max_c_seen;\r
-int max_n_tot;\r
-\r
-} timer_poll_stats;\r
-void dump_poll_stats(void)\r
-{\r
- printf("debug timer poll> n_tot=%d c_seen=%d mnt=%d mcs=%d\n",\r
- timer_poll_stats.n_tot, timer_poll_stats.c_seen,\r
- timer_poll_stats.max_n_tot, timer_poll_stats.max_c_seen);\r
-}\r
-//-------end timer debugging----\r
-\r
-//poll a specific timer group\r
-int netapi_TimerGroupPoll(NETAPI_TIMER_GROUP_HANDLE_T th, int maxTimers)\r
-{\r
-unsigned long long ct= netapi_getTimestamp(); \r
-unsigned long long i;\r
-int cell;\r
-TIM_LIST_T res={NULL,NULL};\r
-int n;\r
-int n_tot=0;\r
-int c_seen=0;\r
-\r
- for(i=((TIMER_GROUP_T*) th)->last_polled; (i<= ct) && (n_tot<maxTimers); )\r
- {\r
- cell = our_hash(i,((TIMER_GROUP_T*) th)->n_cells , ((TIMER_GROUP_T*) th)->cell_width); \r
- tim_return_fired_list(&((TIMER_GROUP_T*) th)->cells[cell],\r
- &res,\r
- &((TIMER_GROUP_T*) th)->free,\r
- i, \r
- &n);\r
- n_tot+=n;\r
- i += ((TIMER_GROUP_T*) th)->cell_width; \r
- c_seen+=1;\r
- }\r
- if (n_tot)\r
- {\r
- ((TIMER_GROUP_T*) th)->cb(th, n_tot, (NETAPI_TIMER_LIST_T) &res, ct);\r
- tim_return_free(&((TIMER_GROUP_T*) th)->free,&res,n_tot);\r
- }\r
-\r
- ((TIMER_GROUP_T*) th)->last_polled = i;\r
- if (c_seen) timer_poll_stats.n_tot = n_tot;\r
- if (c_seen) timer_poll_stats.c_seen = c_seen;\r
- if (n_tot > timer_poll_stats.max_n_tot) timer_poll_stats.max_n_tot = n_tot;\r
- if (c_seen > timer_poll_stats.max_c_seen) timer_poll_stats.max_c_seen = c_seen;\r
- return n_tot;\r
-}\r
-\r
-//poll all timers\r
-int netapi_TimerGroupPollAll(NETAPI_T nh, NETAPI_TIMER_FILTER_T f, int maxTimers)\r
-{\r
- //todo: use filters and poll global, local lists in nh\r
- if (temp_g.h)\r
- netapi_TimerGroupPoll(&temp_g, maxTimers);\r
- return 0;\r
-}\r
-\r
-\r
+/*******************************
+ * FILE: netapi_timer.c
+ * Purpose: implementation of user space timers
+ **************************************************************
+ * FILE: netapi.c
+ *
+ * DESCRIPTION: user space timers 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "netapi.h"
+#include "netapi_timer.h"
+#include "timer_loc.h"
+
+
+/*******************************************************************
+ * hash function: returns cell to place timer object in
+ *
+ ******************************************************************/
+/* static */ int our_hash(
+ unsigned long long ct,
+ int n_cells,
+ unsigned int cell_width)
+{
+int c;
+ //simple hash function
+ c= (ct/cell_width) % n_cells;
+ return c;
+
+}
+
+//iterator on TIMER_LIST_T
+NETAPI_TIMER_T netapi_TimerGetFirst( NETAPI_TIMER_LIST_T list)
+{ return (NETAPI_TIMER_T) ((TIM_LIST_T *)list)->head; }
+
+NETAPI_TIMER_T netapi_TimerGetNext( NETAPI_TIMER_LIST_T list,NETAPI_TIMER_T prev)
+{return prev ? (NETAPI_TIMER_T) ((TIM_T*) prev)->next:NULL ;}
+
+//return cookie associated with timer object
+void * netapi_TimerGetCookie(NETAPI_TIMER_T timer)
+{ return ((TIM_T*) timer)->cookie; }
+
+//return timeer value associated with timer object
+unsigned long long netapi_TimerGetTs(NETAPI_TIMER_T timer)
+{ return ((TIM_T*) timer)->t; }
+
+#if 0
+//timer callback
+typedef void (*NETAPI_TIMER_CB_T) (
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ int n_fired, //# timers fired
+ NETAPI_TIMER_LIST_T fired_list,
+ uint64_t currentTime);
+#endif
+
+static TIMER_GROUP_T temp_g; //temp. todo: put inot netHandle
+
+//create a timer group
+NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupCreate(
+ NETAPI_T netHandle,
+ char * name,
+ NETAPI_TIMER_CB_T cb,
+ int local, //1 if timers local to thread
+ int exp2cancel,//1 if expect to cancel
+ int cell_width, //in ticks
+ int tol, //in ticks
+ int maxTimers,
+ int *pErr)
+{
+ int ret= tim_group_create(&temp_g, TUNE_NETAPI_NUM_TIMER_CELLS, maxTimers);
+ if (!ret) {*pErr = NETAPI_ERR_NOMEM; return NULL;}
+ *pErr=0;
+ temp_g.cb = cb;
+ temp_g.local = local;
+ temp_g.exp2cancel= exp2cancel;
+ temp_g.cell_width=cell_width;
+ temp_g.tol=tol;
+ temp_g.h = netHandle;
+ temp_g.last_polled=(netapi_getTimestamp()/cell_width) * cell_width + (cell_width-1);
+ printf(">timer group %s created. width = %d (ticks)\n", name, cell_width);
+ return (NETAPI_TIMER_GROUP_HANDLE_T) &temp_g;
+}
+
+//open a [global] timer group
+NETAPI_TIMER_GROUP_HANDLE_T netapi_TimerGroupOpen(
+ NETAPI_T netHandle,
+ char * name,
+ NETAPI_TIMER_CB_T cb,
+ int *pErr)
+{
+printf(">timer group open not implemented \n");
+
+}
+
+//start an individual timer
+NETAPI_TIMER_T netapi_TimerGroupStartTimer(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ void * cookie,
+ uint64_t offs2fire, //offset in group ticks
+ int * pErr)
+{
+TIM_T * timer_obj;
+unsigned long long ct= netapi_getTimestamp() + offs2fire* ((TIMER_GROUP_T*) th)->cell_width;
+int cell;
+*pErr=0;
+
+//find cell where to insert
+cell = our_hash(ct,((TIMER_GROUP_T*) th)->n_cells , ((TIMER_GROUP_T*) th)->cell_width);
+
+//get object and insert into this cell
+timer_obj =tim_set(
+ &((TIMER_GROUP_T*) th)->cells[cell],
+ &((TIMER_GROUP_T*) th)->free ,
+ ct,
+ cookie,
+ pErr);
+if (!timer_obj) {return NULL;}
+//DEBUGprintf(">timer: setting timer %x for %lld ticks -> hased to cell %d\n",cookie, ct,cell);
+return (NETAPI_TIMER_T) timer_obj;
+}
+
+//Cancel a timer
+void netapi_TimerGroupCancel(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ NETAPI_TIMER_T timerId,
+ int *pErr)
+{
+ tim_cancel((TIM_T *) timerId, pErr);
+}
+
+//close an opened timer group
+void netapi_TimerGroupClose(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ int *pErr){}
+
+//delete atimer group
+void netapi_TimerGroupDelete(
+ NETAPI_TIMER_GROUP_HANDLE_T th,
+ int *pErr) {printf(">timer group delete not implemented\n");}
+
+//extract netapi handle from timer group handle
+NETAPI_T netap_TimerGroupGetNH( NETAPI_TIMER_GROUP_HANDLE_T th) { return ((TIMER_GROUP_T*) th)->h; }
+
+
+//-----for timer debuggingi-------
+struct
+{
+//last poll stats
+int n_tot;
+int c_seen;
+
+int max_c_seen;
+int max_n_tot;
+
+} timer_poll_stats;
+void dump_poll_stats(void)
+{
+ printf("debug timer poll> n_tot=%d c_seen=%d mnt=%d mcs=%d\n",
+ timer_poll_stats.n_tot, timer_poll_stats.c_seen,
+ timer_poll_stats.max_n_tot, timer_poll_stats.max_c_seen);
+}
+//-------end timer debugging----
+
+//poll a specific timer group
+int netapi_TimerGroupPoll(NETAPI_TIMER_GROUP_HANDLE_T th, int maxTimers)
+{
+unsigned long long ct= netapi_getTimestamp();
+unsigned long long i;
+int cell;
+TIM_LIST_T res={NULL,NULL};
+int n;
+int n_tot=0;
+int c_seen=0;
+
+ for(i=((TIMER_GROUP_T*) th)->last_polled; (i<= ct) && (n_tot<maxTimers); )
+ {
+ cell = our_hash(i,((TIMER_GROUP_T*) th)->n_cells , ((TIMER_GROUP_T*) th)->cell_width);
+ tim_return_fired_list(&((TIMER_GROUP_T*) th)->cells[cell],
+ &res,
+ &((TIMER_GROUP_T*) th)->free,
+ i,
+ &n);
+ n_tot+=n;
+ i += ((TIMER_GROUP_T*) th)->cell_width;
+ c_seen+=1;
+ }
+ if (n_tot)
+ {
+ ((TIMER_GROUP_T*) th)->cb(th, n_tot, (NETAPI_TIMER_LIST_T) &res, ct);
+ tim_return_free(&((TIMER_GROUP_T*) th)->free,&res,n_tot);
+ }
+
+ ((TIMER_GROUP_T*) th)->last_polled = i;
+ if (c_seen) timer_poll_stats.n_tot = n_tot;
+ if (c_seen) timer_poll_stats.c_seen = c_seen;
+ if (n_tot > timer_poll_stats.max_n_tot) timer_poll_stats.max_n_tot = n_tot;
+ if (c_seen > timer_poll_stats.max_c_seen) timer_poll_stats.max_c_seen = c_seen;
+ return n_tot;
+}
+
+//poll all timers
+int netapi_TimerGroupPollAll(NETAPI_T nh, NETAPI_TIMER_FILTER_T f, int maxTimers)
+{
+ //todo: use filters and poll global, local lists in nh
+ if (temp_g.h)
+ netapi_TimerGroupPoll(&temp_g, maxTimers);
+ return 0;
+}
+
+
index 77003686fde0119873ded4b2d3952855df72f050..1cfd679cd63b36f63ea66b72762859e84c08dcff 100755 (executable)
int ip_slot=-1;
NETCP_CFG_CLASS_T classHandle; //returned by us
nwal_appProtoType_t proto;
-nwalLocConnCfg_t tempCfg={
+nwalRxConnCfg_t tempCfg={
0, //nwal_handle: to be filled in
{0}, // l4 ports: to be filled in
0, //core id (NA)
index b6f4d3c44f6ad67569a071bd74b6af94684ab9bb..eb29c1a2496c5dd8f8d211a93a3de52b83bd6ebf 100755 (executable)
#endif
+unsigned long peek(unsigned long * p)
+{
+ return *p;
+}
/**********USE SPACE ACCESS TO KERNEL MEMORY SERVICES*************/
index b5c41d20e7f343282569ccf4c4ce49a3ba23f210..f86f50a6b581e3c86558de70b9ab50cb71aa1a4c 100755 (executable)
PKTIO_HANDLE_T *p=(PKTIO_HANDLE_T*) pp;
*err=0;
r=nwal_pollDm(p->nwalInstanceHandle,
- nwal_POLL_DM_DEF_GLOB_ENCRYPT_Q,
- (uint32_t) p,
- p->max_n,
- QMSS_PARAM_NOT_SPECIFIED,
- (void *) NULL);
- r+=nwal_pollDm(p->nwalInstanceHandle,
- nwal_POLL_DM_DEF_GLOB_DECRYPT_Q,
+ nwal_POLL_DM_DEF_SB_SA_Q,
(uint32_t) p,
p->max_n,
QMSS_PARAM_NOT_SPECIFIED,
else if(p->use_nwal==PKTIO_DEF_SB)
{
r=nwal_pollDm(p->nwalInstanceHandle,
- nwal_POLL_DM_DEF_GLOB_ENCRYPT_Q,
- (uint32_t) p,
- p->max_n,
- QMSS_PARAM_NOT_SPECIFIED,
- (void *) NULL);
- r+=nwal_pollDm(p->nwalInstanceHandle,
- nwal_POLL_DM_DEF_GLOB_DECRYPT_Q,
+ nwal_POLL_DM_DEF_SB_SA_Q,
(uint32_t) p,
p->max_n,
QMSS_PARAM_NOT_SPECIFIED,
index 67098bfb40450a11349af69601a034918516b730..a0535aa8dad0323b3fe07312f7e485d62d6e9dc3 100755 (executable)
-/********************************************************\r
- * File: timer_loc.h\r
- * Purpose: local definitions for timer module\r
- ******************************************************/\r
-\r
-#ifndef __TIMER_LOC__H\r
-#define __TIMER_LOC__H\r
-\r
-\r
-#ifndef NULL\r
-#define NULL 0\r
-#endif\r
-\r
-\r
-/**********************************\r
- * A timer object\r
- * active timrs have non zero cookie\r
- **********************************/\r
-struct TIM_tag;\r
-typedef struct TIM_tag\r
-{\r
-struct TIM_tag * next;\r
-void * cookie;\r
-unsigned long long t;\r
-} TIM_T;\r
-\r
-//a list of timers \r
-typedef struct TIM_LIST_tAG\r
-{\r
- TIM_T * head;\r
- TIM_T * tail;\r
-} TIM_LIST_T;\r
-\r
-\r
-//the timer group context\r
-typedef struct TIMER_GROUP_Tag\r
-{\r
- NETAPI_T h; //back pointer\r
- int n_cells; //#of cells (hash entries)\r
- int n_timers; //# of timer objects\r
- int cell_width; //size of each cell in ticks\r
- TIM_LIST_T free; //free list of timer objects\r
- TIM_LIST_T * cells;//active timers hash table\r
- unsigned long long last_polled; //in ticks\r
- NETAPI_TIMER_CB_T cb; //timer callback\r
- int local; //1 => local timer, 0 =>global timer\r
- int exp2cancel; //1=> expect to cancel, 0=> expect to fire\r
- int tol; //in ticks [FUTURE]\r
-} TIMER_GROUP_T;\r
-\r
-/**********************INTERNAL API*******************/\r
-//create a timer group\r
-int tim_group_create(TIMER_GROUP_T *g, int n_cells, int n_timers);\r
-\r
-//return a list of timer objects to free list\r
-void tim_return_free(TIM_LIST_T *ftl, TIM_LIST_T *p, int n); \r
-\r
-//get a free timer oblject\r
-TIM_T * tim_get_free(TIM_LIST_T *ftl, void *cookie, unsigned long long t);\r
-\r
-//return a list of timers that have fired\r
-void tim_return_fired_list(TIM_LIST_T *tl, TIM_LIST_T * pr, TIM_LIST_T * ftl, unsigned long long t, int * p_nf);\r
-\r
-\r
-//cancel a timer\r
-void tim_cancel(TIM_T * p, int *pErr);\r
-\r
-//insert an active timer into hash cell\r
-TIM_T *tim_set(TIM_LIST_T *tl, TIM_LIST_T *free_tl, unsigned long long t, void *cookie, int *pErr);\r
-\r
-/********************************************************/\r
-/********************internal control of hw*************/\r
-/******************************************************/\r
-//memmap t64 registers. fd is open(/dev/mem)\r
-int t64_memmap(int fd);\r
-\r
-//start the timer \r
-int t64_start(void);\r
-\r
-\r
-#endif\r
+/********************************************************
+ * File: timer_loc.h
+ * Purpose: local definitions for timer module
+ ******************************************************/
+
+#ifndef __TIMER_LOC__H
+#define __TIMER_LOC__H
+
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+
+/**********************************
+ * A timer object
+ * active timrs have non zero cookie
+ **********************************/
+struct TIM_tag;
+typedef struct TIM_tag
+{
+struct TIM_tag * next;
+void * cookie;
+unsigned long long t;
+} TIM_T;
+
+//a list of timers
+typedef struct TIM_LIST_tAG
+{
+ TIM_T * head;
+ TIM_T * tail;
+} TIM_LIST_T;
+
+
+//the timer group context
+typedef struct TIMER_GROUP_Tag
+{
+ NETAPI_T h; //back pointer
+ int n_cells; //#of cells (hash entries)
+ int n_timers; //# of timer objects
+ int cell_width; //size of each cell in ticks
+ TIM_LIST_T free; //free list of timer objects
+ TIM_LIST_T * cells;//active timers hash table
+ unsigned long long last_polled; //in ticks
+ NETAPI_TIMER_CB_T cb; //timer callback
+ int local; //1 => local timer, 0 =>global timer
+ int exp2cancel; //1=> expect to cancel, 0=> expect to fire
+ int tol; //in ticks [FUTURE]
+} TIMER_GROUP_T;
+
+/**********************INTERNAL API*******************/
+//create a timer group
+int tim_group_create(TIMER_GROUP_T *g, int n_cells, int n_timers);
+
+//return a list of timer objects to free list
+void tim_return_free(TIM_LIST_T *ftl, TIM_LIST_T *p, int n);
+
+//get a free timer oblject
+TIM_T * tim_get_free(TIM_LIST_T *ftl, void *cookie, unsigned long long t);
+
+//return a list of timers that have fired
+void tim_return_fired_list(TIM_LIST_T *tl, TIM_LIST_T * pr, TIM_LIST_T * ftl, unsigned long long t, int * p_nf);
+
+
+//cancel a timer
+void tim_cancel(TIM_T * p, int *pErr);
+
+//insert an active timer into hash cell
+TIM_T *tim_set(TIM_LIST_T *tl, TIM_LIST_T *free_tl, unsigned long long t, void *cookie, int *pErr);
+
+/********************************************************/
+/********************internal control of hw*************/
+/******************************************************/
+//memmap t64 registers. fd is open(/dev/mem)
+int t64_memmap(int fd);
+
+//start the timer
+int t64_start(void);
+
+
+#endif
index b5fe712bfb699d0475b3990575ecefef8f3927cd..9eb69d6ea667254dff2167c90b9a65abfb0b3109 100755 (executable)
-/******************************************\r
- * FILE:timlist.c \r
- * Purpose: timer low level primitives\r
- ***********************************************\r
-* FILE:timlist.c\r
- * \r
- * DESCRIPTION: netapi timer library source file for user space transport\r
- * library\r
- * \r
- * REVISION HISTORY: rev 0.0.1 \r
- *\r
- * Copyright (c) Texas Instruments Incorporated 2010-2011\r
- * \r
- * Redistribution and use in source and binary forms, with or without \r
- * modification, are permitted provided that the following conditions \r
- * are met:\r
- *\r
- * Redistributions of source code must retain the above copyright \r
- * notice, this list of conditions and the following disclaimer.\r
- *\r
- * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the \r
- * documentation and/or other materials provided with the \r
- * distribution.\r
- *\r
- * Neither the name of Texas Instruments Incorporated nor the names of\r
- * its contributors may be used to endorse or promote products derived\r
- * from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-\r
- ***************************************/\r
-//#define TEST_DRIVER\r
-#ifdef TEST_DRIVER\r
-typedef void * NETAPI_T;\r
-typedef void * NETAPI_TIMER_CB_T;\r
-#else\r
-#include "../netapi_timer.h"\r
-#endif\r
-#include "timer_loc.h"\r
-#include "../netapi_err.h"\r
-\r
-#ifndef NULL\r
-#define NULL 0\r
-#endif\r
-\r
-\r
-//create a timer group\r
-int tim_group_create(TIMER_GROUP_T *g, int n_cells, int n_timers)\r
-{\r
-char * mem= (char *) malloc(n_timers * sizeof (TIM_T));\r
-if (!mem) return -1;\r
-g->n_cells = n_cells;\r
-tim_build_free(&g->free, mem, sizeof(TIM_T) * n_timers);\r
-g->cells=(TIM_LIST_T *) malloc(n_cells * sizeof(TIM_LIST_T));\r
-if (!g->cells) {free(mem); return -1;}\r
-g->n_timers=n_timers;\r
-g->last_polled=0;\r
-return 1;\r
-}\r
-\r
-//return as single timer to end of free list, zero cookie, etc\r
-void tim_return_single_free(TIM_LIST_T *ftl, TIM_T *p)\r
-{\r
-TIM_T * pt;\r
-int i;\r
-pt = ftl->tail;\r
-if (!pt)\r
-{\r
-ftl->head=p;\r
-ftl->tail=p;\r
-}\r
-else\r
-{\r
-pt->next=p;\r
-ftl->tail = p;\r
-}\r
- p->t=0LL;\r
- p->cookie=NULL;\r
- p->next=NULL;\r
-}\r
-\r
-\r
-//return a list of N timers to end of [free] list. zero cookie, etc \r
-void tim_return_free(TIM_LIST_T *ftl, TIM_LIST_T *p, int n)\r
-{\r
-TIM_T * pt;\r
-int i;\r
-pt = ftl->tail;\r
-if (!pt) \r
-{\r
-ftl->head=p->head;\r
-ftl->tail=p->tail;\r
-}\r
-else \r
-{\r
-pt->next=p->head;\r
-ftl->tail = p->tail;\r
-}\r
-\r
-pt= p->head;\r
-for(i=0;i<n;i++)\r
-{\r
- pt->t=0LL;\r
- pt->cookie=NULL;\r
- pt= pt->next;\r
-}\r
-ftl->tail->next=NULL;\r
-}\r
-\r
-//get a [free] entry from front of a list \r
-TIM_T * tim_get_free(TIM_LIST_T *tl, void *cookie, unsigned long long t)\r
-{\r
-TIM_T *p = tl->head;\r
-if (p)\r
-{\r
- tl->head=p->next;\r
- p->next=NULL;\r
- p->cookie = cookie;\r
- p->t = t;\r
- if (!tl->head) tl->tail=NULL;\r
-}\r
-return p;\r
-}\r
-\r
-//build a timer list from chunk of memory\r
-int tim_build_free(TIM_LIST_T *tl, char *p_mem, int mem_size)\r
-{\r
-TIM_T * p = (TIM_T*) p_mem;\r
-TIM_T * p_old = (TIM_T*) p_mem;\r
-int i=0;\r
-tl->head = p;\r
-while(mem_size)\r
-{\r
- p_old = p;\r
- p->cookie=NULL;\r
- p->t = 0LL;\r
- mem_size -= sizeof(TIM_T);\r
- p+=1;\r
- i+=1;\r
- p_old->next=p;\r
-}\r
-p_old->next = NULL;\r
-tl->tail = p_old;\r
-return i;\r
-}\r
-\r
-//return a list of timers that have fired\r
-void tim_return_fired_list(TIM_LIST_T *tl, TIM_LIST_T * pr, TIM_LIST_T * ftl, unsigned long long t, int * p_nf)\r
-{\r
-int i=0;\r
-int got_start=0;\r
-int found_end=0;\r
-TIM_T * p_last, *p, *temp_p_next;\r
-TIM_LIST_T p_free={NULL,NULL};\r
-if (! tl->head) { *p_nf=0; return ;}\r
-\r
-p = tl->head;\r
-p_last= NULL; \r
-\r
-for(i=0;p;)\r
-{\r
- if(p->t <= t) \r
- {\r
- if(!got_start)\r
- {\r
- if(p->cookie)\r
- {\r
- //start results chain\r
- got_start=1;\r
- if(pr->tail) {pr->tail->next = p; pr->tail=p;}\r
- else {pr->head=pr->tail = p;}\r
- i+=1;\r
- p_last=p;\r
- p=p->next;\r
- continue;\r
- }\r
- else //skip over cancelled timer..\r
- {\r
- //skip & free. make sure we adjust head or tail if necessary\r
- if (p_last){\r
- p_last->next=p->next; \r
- }\r
- else {\r
- tl->head = p->next; /* we are freeing old head..*/\r
- }\r
- if (tl->tail ==p) tl->tail=p_last; /* we are freeing old tail */\r
- temp_p_next=p->next;\r
- tim_return_single_free(ftl,p);\r
- p=temp_p_next; \r
- /*keep p_last the same! */\r
- continue; \r
- }\r
- } \r
- else\r
- {\r
- if(!p->cookie)\r
- {\r
- //skip & free\r
- if (p_last){ \r
- p_last->next=p->next; \r
- }\r
- else {\r
- tl->head = p->next;\r
- }\r
- if (tl->tail ==p) tl->tail=p_last; /* we are freeing old tail */\r
- temp_p_next=p->next;\r
- tim_return_single_free(ftl,p);\r
- p=temp_p_next; \r
- /*keep p_last the same! */\r
- continue;\r
- } \r
- else { //valid entry for list.\r
- p_last=p; \r
- p=p->next;\r
- i+=1;\r
- continue;\r
- } \r
- }\r
- }\r
- else /* p->t > t */\r
- {\r
- if(got_start)\r
- {\r
- found_end =1; //found end of chain to return. All is good\r
- pr->tail = p_last;\r
- p_last->next=NULL;\r
- tl->head=p;\r
- }\r
- // done\r
- break;\r
- }\r
-}\r
-\r
-*p_nf=i;\r
-if ((got_start) && (!found_end)) \r
-{\r
- //cleared the list\r
- //DEBUGprintf("clearingthelist\n");\r
- tl->head = tl->tail=NULL;\r
-}\r
-return;\r
-}\r
-\r
-//cancel a timer\r
-void tim_cancel(TIM_T * p, int *pErr)\r
-{\r
- *pErr =0;\r
- if (!p) {*pErr = NETAPI_ERR_BAD_INPUT; return; }\r
- if (!p->cookie) {*pErr= NETAPI_ERR_ALREADY_CANCELLED; return;}\r
- p->cookie = NULL;\r
- return;\r
-}\r
-\r
-//set a timer \r
-TIM_T *tim_set(TIM_LIST_T *tl, TIM_LIST_T *free_tl, unsigned long long t, void *cookie, int *pErr)\r
-{\r
-TIM_T *pt = tl->head;\r
-TIM_T *p = tim_get_free(free_tl, cookie, t);\r
-TIM_T *pt_last= NULL;\r
-int i;\r
-*pErr=0;\r
-if (!p ) { *pErr=NETAPI_ERR_NOMEM; return NULL;} \r
-\r
-if (!pt) //first one\r
-{\r
- tl->head = p;\r
- tl->tail =p;\r
- return p; \r
-}\r
-\r
-//see if we can place at front of list\r
-if (pt->t >=t)\r
-{\r
- tl->head=p;\r
- p->next=pt;\r
- return p;\r
-}\r
-\r
- //timer has hashed into this chain. find out where\r
-for(;pt;)\r
-{\r
- if (pt->t >= t) \r
- {\r
- if (pt_last) {\r
- pt_last->next = p;\r
- p->next=pt;\r
- return p;\r
- }\r
- else\r
- {\r
- tl->head=p;\r
- p->next=pt;\r
- return p;\r
- }\r
- }\r
- else {pt_last=pt;pt=pt->next;}\r
-}\r
-//last one\r
-pt_last->next=p;\r
-p->next=NULL;\r
-tl->tail=p;\r
-return p;\r
-}\r
-\r
-#ifdef TEST_DRIVER\r
-TIM_LIST_T the_base={NULL,NULL};\r
-TIM_LIST_T cell_base={NULL,NULL};\r
-char *mem;\r
-TIM_T * timers[10];\r
-TIM_LIST_T res;\r
-main()\r
-{\r
- int err;\r
- mem= malloc(100*sizeof(TIM_T));\r
- TIM_T *p;\r
- int n;\r
- int i;\r
- \r
- tim_build_free(&the_base, mem , 100*sizeof(TIM_T));\r
-\r
- timers[0]=tim_set(&cell_base, &the_base, 100LL, (void *) 1, &err);\r
- timers[1]=tim_set(&cell_base, &the_base, 101LL, (void *) 2, &err);\r
- timers[2]=tim_set(&cell_base, &the_base, 105LL, (void *) 3, &err);\r
- timers[3]=tim_set(&cell_base, &the_base, 95LL, (void *) 4, &err);\r
- timers[4]=tim_set(&cell_base, &the_base, 95LL, (void *) 5, &err);\r
- timers[5]=tim_set(&cell_base, &the_base, 95LL, (void *) 6, &err);\r
- timers[6]=tim_set(&cell_base, &the_base, 104LL, (void *) 7, &err);\r
- timers[7]=tim_set(&cell_base, &the_base, 104LL, (void *) 8, &err);\r
- timers[8]=tim_set(&cell_base, &the_base, 104LL, (void *) 9, &err);\r
-\r
- tim_cancel(timers[6], &err);\r
-\r
-\r
- res.head=res.tail=NULL;\r
-for(i=90;i<106;i++)\r
- {\r
-tim_return_fired_list(&cell_base, &res, &the_base, (unsigned long long) i, &n);\r
- printf("at %d got %d\n", i, n);\r
- if (n) {tim_return_free(&the_base,&res,n); res.head=res.tail=NULL;\r
-\r
- }\r
-\r
-//special cases..\r
- res.head=res.tail=NULL;\r
- timers[0]=tim_set(&cell_base, &the_base, 106LL, (void *)10, &err);\r
- tim_cancel(timers[0],&err);\r
- tim_return_fired_list(&cell_base, &res, &the_base, (unsigned long long) 106, &n);\r
- \r
- res.head=res.tail=NULL;\r
- timers[0]=tim_set(&cell_base, &the_base, 106LL, (void *)10, &err);\r
- timers[1]=tim_set(&cell_base, &the_base, 106LL, (void *)10, &err);\r
- tim_cancel(timers[0],&err);\r
- tim_return_fired_list(&cell_base, &res, &the_base, (unsigned long long) 106, &n);\r
-\r
- res.head=res.tail=NULL;\r
- timers[0]=tim_set(&cell_base, &the_base, 106LL, (void *)10, &err);\r
- timers[1]=tim_set(&cell_base, &the_base, 106LL, (void *)10, &err);\r
- tim_cancel(timers[0],&err);\r
- tim_cancel(timers[1],&err);\r
- tim_return_fired_list(&cell_base, &res, &the_base, (unsigned long long) 106, &n);\r
- \r
-}\r
-#endif\r
+/******************************************
+ * FILE:timlist.c
+ * Purpose: timer low level primitives
+ ***********************************************
+* FILE:timlist.c
+ *
+ * DESCRIPTION: netapi timer library 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.
+
+ ***************************************/
+//#define TEST_DRIVER
+#ifdef TEST_DRIVER
+typedef void * NETAPI_T;
+typedef void * NETAPI_TIMER_CB_T;
+#else
+#include "../netapi_timer.h"
+#endif
+#include "timer_loc.h"
+#include "../netapi_err.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+
+//create a timer group
+int tim_group_create(TIMER_GROUP_T *g, int n_cells, int n_timers)
+{
+char * mem= (char *) malloc(n_timers * sizeof (TIM_T));
+if (!mem) return -1;
+g->n_cells = n_cells;
+tim_build_free(&g->free, mem, sizeof(TIM_T) * n_timers);
+g->cells=(TIM_LIST_T *) malloc(n_cells * sizeof(TIM_LIST_T));
+if (!g->cells) {free(mem); return -1;}
+g->n_timers=n_timers;
+g->last_polled=0;
+return 1;
+}
+
+//return as single timer to end of free list, zero cookie, etc
+void tim_return_single_free(TIM_LIST_T *ftl, TIM_T *p)
+{
+TIM_T * pt;
+int i;
+pt = ftl->tail;
+if (!pt)
+{
+ftl->head=p;
+ftl->tail=p;
+}
+else
+{
+pt->next=p;
+ftl->tail = p;
+}
+ p->t=0LL;
+ p->cookie=NULL;
+ p->next=NULL;
+}
+
+
+//return a list of N timers to end of [free] list. zero cookie, etc
+void tim_return_free(TIM_LIST_T *ftl, TIM_LIST_T *p, int n)
+{
+TIM_T * pt;
+int i;
+pt = ftl->tail;
+if (!pt)
+{
+ftl->head=p->head;
+ftl->tail=p->tail;
+}
+else
+{
+pt->next=p->head;
+ftl->tail = p->tail;
+}
+
+pt= p->head;
+for(i=0;i<n;i++)
+{
+ pt->t=0LL;
+ pt->cookie=NULL;
+ pt= pt->next;
+}
+ftl->tail->next=NULL;
+}
+
+//get a [free] entry from front of a list
+TIM_T * tim_get_free(TIM_LIST_T *tl, void *cookie, unsigned long long t)
+{
+TIM_T *p = tl->head;
+if (p)
+{
+ tl->head=p->next;
+ p->next=NULL;
+ p->cookie = cookie;
+ p->t = t;
+ if (!tl->head) tl->tail=NULL;
+}
+return p;
+}
+
+//build a timer list from chunk of memory
+int tim_build_free(TIM_LIST_T *tl, char *p_mem, int mem_size)
+{
+TIM_T * p = (TIM_T*) p_mem;
+TIM_T * p_old = (TIM_T*) p_mem;
+int i=0;
+tl->head = p;
+while(mem_size)
+{
+ p_old = p;
+ p->cookie=NULL;
+ p->t = 0LL;
+ mem_size -= sizeof(TIM_T);
+ p+=1;
+ i+=1;
+ p_old->next=p;
+}
+p_old->next = NULL;
+tl->tail = p_old;
+return i;
+}
+
+//return a list of timers that have fired
+void tim_return_fired_list(TIM_LIST_T *tl, TIM_LIST_T * pr, TIM_LIST_T * ftl, unsigned long long t, int * p_nf)
+{
+int i=0;
+int got_start=0;
+int found_end=0;
+TIM_T * p_last, *p, *temp_p_next;
+TIM_LIST_T p_free={NULL,NULL};
+if (! tl->head) { *p_nf=0; return ;}
+
+p = tl->head;
+p_last= NULL;
+
+for(i=0;p;)
+{
+ if(p->t <= t)
+ {
+ if(!got_start)
+ {
+ if(p->cookie)
+ {
+ //start results chain
+ got_start=1;
+ if(pr->tail) {pr->tail->next = p; pr->tail=p;}
+ else {pr->head=pr->tail = p;}
+ i+=1;
+ p_last=p;
+ p=p->next;
+ continue;
+ }
+ else //skip over cancelled timer..
+ {
+ //skip & free. make sure we adjust head or tail if necessary
+ if (p_last){
+ p_last->next=p->next;
+ }
+ else {
+ tl->head = p->next; /* we are freeing old head..*/
+ }
+ if (tl->tail ==p) tl->tail=p_last; /* we are freeing old tail */
+ temp_p_next=p->next;
+ tim_return_single_free(ftl,p);
+ p=temp_p_next;
+ /*keep p_last the same! */
+ continue;
+ }
+ }
+ else
+ {
+ if(!p->cookie)
+ {
+ //skip & free
+ if (p_last){
+ p_last->next=p->next;
+ }
+ else {
+ tl->head = p->next;
+ }
+ if (tl->tail ==p) tl->tail=p_last; /* we are freeing old tail */
+ temp_p_next=p->next;
+ tim_return_single_free(ftl,p);
+ p=temp_p_next;
+ /*keep p_last the same! */
+ continue;
+ }
+ else { //valid entry for list.
+ p_last=p;
+ p=p->next;
+ i+=1;
+ continue;
+ }
+ }
+ }
+ else /* p->t > t */
+ {
+ if(got_start)
+ {
+ found_end =1; //found end of chain to return. All is good
+ pr->tail = p_last;
+ p_last->next=NULL;
+ tl->head=p;
+ }
+ // done
+ break;
+ }
+}
+
+*p_nf=i;
+if ((got_start) && (!found_end))
+{
+ //cleared the list
+ //DEBUGprintf("clearingthelist\n");
+ tl->head = tl->tail=NULL;
+}
+return;
+}
+
+//cancel a timer
+void tim_cancel(TIM_T * p, int *pErr)
+{
+ *pErr =0;
+ if (!p) {*pErr = NETAPI_ERR_BAD_INPUT; return; }
+ if (!p->cookie) {*pErr= NETAPI_ERR_ALREADY_CANCELLED; return;}
+ p->cookie = NULL;
+ return;
+}
+
+//set a timer
+TIM_T *tim_set(TIM_LIST_T *tl, TIM_LIST_T *free_tl, unsigned long long t, void *cookie, int *pErr)
+{
+TIM_T *pt = tl->head;
+TIM_T *p = tim_get_free(free_tl, cookie, t);
+TIM_T *pt_last= NULL;
+int i;
+*pErr=0;
+if (!p ) { *pErr=NETAPI_ERR_NOMEM; return NULL;}
+
+if (!pt) //first one
+{
+ tl->head = p;
+ tl->tail =p;
+ return p;
+}
+
+//see if we can place at front of list
+if (pt->t >=t)
+{
+ tl->head=p;
+ p->next=pt;
+ return p;
+}
+
+ //timer has hashed into this chain. find out where
+for(;pt;)
+{
+ if (pt->t >= t)
+ {
+ if (pt_last) {
+ pt_last->next = p;
+ p->next=pt;
+ return p;
+ }
+ else
+ {
+ tl->head=p;
+ p->next=pt;
+ return p;
+ }
+ }
+ else {pt_last=pt;pt=pt->next;}
+}
+//last one
+pt_last->next=p;
+p->next=NULL;
+tl->tail=p;
+return p;
+}
+
+#ifdef TEST_DRIVER
+TIM_LIST_T the_base={NULL,NULL};
+TIM_LIST_T cell_base={NULL,NULL};
+char *mem;
+TIM_T * timers[10];
+TIM_LIST_T res;
+main()
+{
+ int err;
+ mem= malloc(100*sizeof(TIM_T));
+ TIM_T *p;
+ int n;
+ int i;
+
+ tim_build_free(&the_base, mem , 100*sizeof(TIM_T));
+
+ timers[0]=tim_set(&cell_base, &the_base, 100LL, (void *) 1, &err);
+ timers[1]=tim_set(&cell_base, &the_base, 101LL, (void *) 2, &err);
+ timers[2]=tim_set(&cell_base, &the_base, 105LL, (void *) 3, &err);
+ timers[3]=tim_set(&cell_base, &the_base, 95LL, (void *) 4, &err);
+ timers[4]=tim_set(&cell_base, &the_base, 95LL, (void *) 5, &err);
+ timers[5]=tim_set(&cell_base, &the_base, 95LL, (void *) 6, &err);
+ timers[6]=tim_set(&cell_base, &the_base, 104LL, (void *) 7, &err);
+ timers[7]=tim_set(&cell_base, &the_base, 104LL, (void *) 8, &err);
+ timers[8]=tim_set(&cell_base, &the_base, 104LL, (void *) 9, &err);
+
+ tim_cancel(timers[6], &err);
+
+
+ res.head=res.tail=NULL;
+for(i=90;i<106;i++)
+ {
+tim_return_fired_list(&cell_base, &res, &the_base, (unsigned long long) i, &n);
+ printf("at %d got %d\n", i, n);
+ if (n) {tim_return_free(&the_base,&res,n); res.head=res.tail=NULL;
+
+ }
+
+//special cases..
+ res.head=res.tail=NULL;
+ timers[0]=tim_set(&cell_base, &the_base, 106LL, (void *)10, &err);
+ tim_cancel(timers[0],&err);
+ tim_return_fired_list(&cell_base, &res, &the_base, (unsigned long long) 106, &n);
+
+ res.head=res.tail=NULL;
+ timers[0]=tim_set(&cell_base, &the_base, 106LL, (void *)10, &err);
+ timers[1]=tim_set(&cell_base, &the_base, 106LL, (void *)10, &err);
+ tim_cancel(timers[0],&err);
+ tim_return_fired_list(&cell_base, &res, &the_base, (unsigned long long) 106, &n);
+
+ res.head=res.tail=NULL;
+ timers[0]=tim_set(&cell_base, &the_base, 106LL, (void *)10, &err);
+ timers[1]=tim_set(&cell_base, &the_base, 106LL, (void *)10, &err);
+ tim_cancel(timers[0],&err);
+ tim_cancel(timers[1],&err);
+ tim_return_fired_list(&cell_base, &res, &the_base, (unsigned long long) 106, &n);
+
+}
+#endif
index 691208e6e7ddc06cd17695dac327265ecda33b0a..6519591df9d35bc379a0dd933e2d4d4c6fc98965 100755 (executable)
CPPI_INC_DIR = $(PDK_INSTALL_PATH)/ti/drv/cppi
NETAPI_INC_DIR = $(NETAPI_INSTALL_PATH)/ti/runtime/netapi
+SA_INC_DIR = $(SA_INSTALL_PATH)
#NETAPI LIB Build directory
NETAPI_BUILD_DIR = $(NETAPI_INC_DIR)/build
CC = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)gcc
AR = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)ar -r
-CFLAGS= $(DEBUG_FLAG) -I../ -I. -I$(NETAPI_INC_DIR) -I$(NETAPI_INC_DIR)/src -I$(PDK_INSTALL_PATH) -I$(NWAL_INSTALL_PATH) -I$(PKTLIB_INSTALL_PATH) -I$(TRANS_SDK_INSTALL_PATH) -I$(QMSS_INC_DIR) -I$(CPPI_INC_DIR) -D__ARMv7 -D_VIRTUAL_ADDR_SUPPORT -D__LINUX_USER_SPACE -D_LITTLE_ENDIAN=1 -DMAKEFILE_BUILD -pthread -D _GNU_SOURCE
+CFLAGS= $(DEBUG_FLAG) -I../ -I. -I$(NETAPI_INC_DIR) -I$(NETAPI_INC_DIR)/src -I$(PDK_INSTALL_PATH) -I$(NWAL_INSTALL_PATH) -I$(PKTLIB_INSTALL_PATH) -I$(TRANS_SDK_INSTALL_PATH) -I$(QMSS_INC_DIR) -I$(CPPI_INC_DIR) -I$(SA_INC_DIR) -D__ARMv7 -D_VIRTUAL_ADDR_SUPPORT -D__LINUX_USER_SPACE -D_LITTLE_ENDIAN=1 -DMAKEFILE_BUILD -pthread -D _GNU_SOURCE
# Linker options
INTERNALLINKDEFS = --start-group -L$(ARMV7LIBDIR) -L$(PDK_ARMV7LIBDIR) $(NETAPI_LIB) $(PKTLIB_LIB) $(QMSS_LIB) $(CPPI_LIB) $(NWAL_LIB) $(PA_LIB) $(SA_LIB) $(AES_LIB) $(SHA1_LIB) $(PKTUTL_LIB) -lrt --end-group
all: tests
-tests: $(ARMV7BINDIR)/netapi/test/.created $(ARMV7BINDIR)/netapi/test/net_test $(ARMV7BINDIR)/netapi/test/synchtest $(ARMV7BINDIR)/netapi/test/synchtest2
+tests: $(ARMV7BINDIR)/netapi/test/.created $(ARMV7BINDIR)/netapi/test/net_test $(ARMV7BINDIR)/netapi/test/synchtest $(ARMV7BINDIR)/netapi/test/synchtest2 $(ARMV7BINDIR)/netapi/test/udpif
api_clean:
rm -f $(ARMV7LIBDIR)/libnetapi.a
clean:
rm -f $(ARMV7OBJDIR)/netapi/test/*.o
rm -f $(ARMV7LIBDIR)/libnetapi.a
- rm -f $(ARMV7BINDIR)/netapi/test/net_test $(ARMV7BINDIR)/netapi/test/synchtest $(ARMV7BINDIR)/netapi/test/synchtest2
+ rm -f $(ARMV7BINDIR)/netapi/test/net_test $(ARMV7BINDIR)/netapi/test/synchtest $(ARMV7BINDIR)/netapi/test/synchtest2 $(ARMV7BINDIR)/netapi/test/udpif
$(ARMV7OBJDIR)/netapi/test/%.o:$(NETAPI_INC_DIR)/test/%.c $(ARMV7OBJDIR)/netapi/test/.created
$(ARMV7BINDIR)/netapi/test/synchtest2: $(ARMV7OBJDIR)/netapi/test/synchtest2.o
$(CC) $(LDFLAGS) $(ARMV7OBJDIR)/netapi/test/synchtest2.o -o $(ARMV7BINDIR)/netapi/test/synchtest2 -lpthread
-
+
+$(ARMV7BINDIR)/netapi/test/udpif: $(ARMV7OBJDIR)/netapi/test/udpif.o
+ $(CC) $(LDFLAGS) $(ARMV7OBJDIR)/netapi/test/udpif.o -o $(ARMV7BINDIR)/netapi/test/udpif
#include "netapi.h"
#include "pktio.h"
#include <sys/resource.h>
+#include "net_test.h"
+#include <ti/drv/sa/salld.h>
+#define EXPERIMENTAL
+#ifdef EXPERIMENTAL
+#include "router.c"
+Trie * our_router;
+
+OUR_ROUTE_T routes[MAX_ROUTES]=
+{
+{0,{0xD4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x14,0x02,0x08,0x00},0},
+{0,{0x00,0x00,0x0,0x00,0x0,0x0, 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00},0},
+{0,{0xD4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x14,0x02,0x08,0x00},0},
+{0,{0x00,0x15,0x60,0xa1,0xf7,0xbe, 0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00},0},
+{0,{0xd4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00},0}};
-//IPSEC MODE(only choose one rx and one tx)
-#define IPSEC_MODE_RX_INFLOW
-#define IPSEC_MODE_TX_INFLOW
-//#define IPSEC_MODE_RX_SIDEBAND
-//#define IPSEC_MODE_TX_SIDEBAND
+unsigned int ip[MAX_ROUTES]={BE(0x0a0100c8),BE(0x0a00000a),BE(0x0a02000a),BE(0xc0a8010a),BE(0x9eda6719)};
+#endif
//#define TEST_TIMERS
/*************debug********************/
};
+char input_file_name[] = "net_test_config.txt";
+#define MAX_LINE_LENGTH 40
+
#define TEST_PAYLOAD_LEN 80
#define TEST_PKT_IP_OFFSET_BYTES 14
void example_fast_poll( PKTIO_HANDLE_T * p_pktio, int max_pkts);
void example_fast_pushpop(Pktlib_HeapHandle p_heap, int ntrials);
+void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
+ PKTIO_METADATA_T meta[], int n_pkts,
+ uint64_t ts );
+
-#if 1
//#include "arpa/inet.h"
long htonl(long x)
{
-#endif
-typedef struct stats_t
-{
- long itx; //initially generated
- long itx2;
- long rx;
- long tx;
- long n_bad;
- long n_new;
- long n_class0_rx; //count of pkts classified
- long n_class1_rx; //count of pkts classified
- long n_class2_rx; //count of pkts classified
- long n_t1;
- long n_t2;
- long n_t3;
- long sec_tx;
- long sec_rx;
- long sb_tx;
- long sb_rx;
- long secp_rx;
- long n_auth_ok;
-} 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 };
-nwalIpAddr_t OurIp2={ 10, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-nwalIpAddr_t OurIp4IPSEC={ 192,168 , 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-nwalIpAddr_t TheirIp4IPSEC={ 192,168 , 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
+/* net test default configuration */
+netTestConfig_t config =
+{
+ {0x00,0x01,0x02,0x03,0x05,0x05},
+ {0x00,0x01,0x02,0x03,0x05,0x06},
+ {10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {10, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {192,168 , 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ {192,168 , 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ IPSEC_MODE_RX_SIDEBAND,
+ IPSEC_MODE_TX_SIDEBAND,
+ 0
+};
#if 1 //goes with real tx (to laptop)
unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,
STATS_T stats;
Trie * P_trie;
+Trie *p_trie_sa;
HEAD_T pkts[NP];
#define PERSLOW 10 //% of pkts that will not be fastpath'd
int perslow= PERSLOW;
NETAPI_T netapi_handle;
NETAPI_SCHED_HANDLE_T * our_sched;
NETAPI_SCHED_CONFIG_T our_sched_cfg={
- NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 50000 //every 5000 poll loops
+ NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000 //every 5000000 poll loops
};
void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock;
PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};
/* security objects. (for loopback mode) */
-NETCP_CFG_SA_T rx_tunnel;
-NETCP_CFG_SA_T tx_tunnel;
-NETCP_CFG_IPSEC_POLICY_T rx_policy;
-void * rx_data_mode_handle;
-void * tx_data_mode_handle;
-void * rx_inflow_mode_handle;
-void * tx_inflow_mode_handle;
+netTestSA_t sa_info[6];
+int netapi_algorithm_set = 0;
+int netapi_sec_sa_mode = 2;
+/* tmannan-end */
+//NETCP_CFG_SA_T rx_tunnel;
+//NETCP_CFG_SA_T tx_tunnel;
+NETCP_CFG_IPSEC_POLICY_T rx_policy[4];
+//void * rx_data_mode_handle;
+//void * tx_data_mode_handle;
+//void * rx_inflow_mode_handle;
+//void * tx_inflow_mode_handle;
/* rx */
-NETAPI_SEC_SA_INFO_T rx_sa=
-{
- NWAL_SA_DIR_INBOUND,
- 0x44444444, //spi
- nwal_IpSecProtoESP, //ESP mode
- nwal_SA_MODE_TUNNEL, //tunnel mode
- nwal_IPV4, //v4
- { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (them) -> set below */
- { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (us)-> set below*/
- 64,/* replayWindow */
- NWAL_SA_AALG_HMAC_SHA1,
- NWAL_SA_EALG_AES_CBC,
- 0,0 //na
+
+
+NETAPI_SEC_SA_INFO_T rx_sa [4] = {
+{
+ NWAL_SA_DIR_INBOUND,
+ 0x11111111, //spi
+ nwal_IpSecProtoESP, //ESP mode
+ nwal_SA_MODE_TUNNEL, //tunnel mode
+ nwal_IPV4, //v4
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (them) -> set below */
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (us)-> set below*/
+ 64,/* replayWindow */
+ NWAL_SA_AALG_HMAC_SHA1,
+ NWAL_SA_EALG_AES_CBC,
+ 0,0 //na
+},
+{
+ NWAL_SA_DIR_INBOUND,
+ 0x22222222, //spi
+ nwal_IpSecProtoESP, //ESP mode
+ nwal_SA_MODE_TUNNEL, //tunnel mode
+ nwal_IPV4, //v4
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (them) -> set below */
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (us)-> set below*/
+ 64,/* replayWindow */
+ NWAL_SA_AALG_HMAC_SHA2_256,
+ NWAL_SA_EALG_AES_CTR,
+ 0,0 //na
+},
+{
+ NWAL_SA_DIR_INBOUND,
+ 0x33333333, //spi
+ nwal_IpSecProtoESP, //ESP mode
+ nwal_SA_MODE_TUNNEL, //tunnel mode
+ nwal_IPV4, //v4
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (them) -> set below */
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (us)-> set below*/
+ 64,/* replayWindow */
+ NWAL_SA_AALG_HMAC_SHA2_256,
+ NWAL_SA_EALG_3DES_CBC,
+ 0,0 //na
+},
+{
+ NWAL_SA_DIR_INBOUND,
+ 0x44444444, //spi
+ nwal_IpSecProtoESP, //ESP mode
+ nwal_SA_MODE_TUNNEL, //tunnel mode
+ nwal_IPV4, //v4
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (them) -> set below */
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (us)-> set below*/
+ 64,/* replayWindow */
+ NWAL_SA_AALG_HMAC_MD5,
+ NWAL_SA_EALG_NULL,
+ 0,0 //na
+}
};
/*tx */
-NETAPI_SEC_SA_INFO_T tx_sa=
-{
- NWAL_SA_DIR_OUTBOUND,
- 0x44444444, //spi
- nwal_IpSecProtoESP, //ESP mode
- nwal_SA_MODE_TUNNEL, //tunnel mode
- nwal_IPV4, //v4
- { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (us) -> set below */
- { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (them) -> set below*/
- 64, /* NA replayWindow */
- NWAL_SA_AALG_HMAC_SHA1,
- NWAL_SA_EALG_AES_CBC,
- 0,0 //seq no
+NETAPI_SEC_SA_INFO_T tx_sa[4]= {
+{
+ NWAL_SA_DIR_OUTBOUND,
+ 0x11111111, //spi
+ nwal_IpSecProtoESP, //ESP mode
+ nwal_SA_MODE_TUNNEL, //tunnel mode
+ nwal_IPV4, //v4
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (us) -> set below */
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (them) -> set below*/
+ 64, /* NA replayWindow */
+ NWAL_SA_AALG_HMAC_SHA1,
+ NWAL_SA_EALG_AES_CBC,
+ 0,0 //seq no
+},
+ {
+ NWAL_SA_DIR_OUTBOUND,
+ 0x22222222, //spi
+ nwal_IpSecProtoESP, //ESP mode
+ nwal_SA_MODE_TUNNEL, //tunnel mode
+ nwal_IPV4, //v4
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (us) -> set below */
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (them) -> set below*/
+ 64, /* NA replayWindow */
+ NWAL_SA_AALG_HMAC_SHA2_256,
+ NWAL_SA_EALG_AES_CTR,
+ 0,0 //seq no
+},
+{
+ NWAL_SA_DIR_OUTBOUND,
+ 0x33333333, //spi
+ nwal_IpSecProtoESP, //ESP mode
+ nwal_SA_MODE_TUNNEL, //tunnel mode
+ nwal_IPV4, //v4
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (us) -> set below */
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (them) -> set below*/
+ 64, /* NA replayWindow */
+ NWAL_SA_AALG_HMAC_SHA2_256,
+ NWAL_SA_EALG_3DES_CBC,
+ 0,0 //seq no
+},
+{
+ NWAL_SA_DIR_OUTBOUND,
+ 0x44444444, //spi
+ nwal_IpSecProtoESP, //ESP mode
+ nwal_SA_MODE_TUNNEL, //tunnel mode
+ nwal_IPV4, //v4
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (us) -> set below */
+ { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (them) -> set below*/
+ 64, /* NA replayWindow */
+ NWAL_SA_AALG_HMAC_MD5,
+ NWAL_SA_EALG_NULL,
+ 0,0 //seq no
+}
};
-//since we are doing loopback, the rx key params = tx key params
-static nwalSecKeyParams_t ourTXKeyParams =
+static nwalSecKeyParams_t ourTXKeyParams[4] ={
+{
+ 16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/
+ 20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA1 */
+ NULL, //set below
+ NULL, //set below
+},
{
- 16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_DES_CBC and 0 bytes Salt*/
- 20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_MD5 */
+ 20, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_AES_CTR and 0 bytes Salt*/
+ 32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */
NULL, //set below
NULL, //set below
+},
+{
+ 24, /* encKeySize: DES-CBC: 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/
+ 32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */
+ NULL, //set below
+ NULL, //set below
+},
+{
+ 0, /* NULL*/
+ 16, /* MD5, 16 bytes */
+ NULL, //set below
+ NULL, //set below
+}
};
-static nwalSecKeyParams_t ourRXKeyParams ={
- 16, /* encKeySize: 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_DES_CBC and 0 bytes Salt*/
- 20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_MD5 */
+/* these keys are for aes-ctr and hmac sha2_256 */
+static nwalSecKeyParams_t ourRXKeyParams[4] ={
+{
+ 16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/
+ 20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA1 */
+ NULL, //set below
+ NULL, //set below
+},
+{
+ 20, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_AES_CTR and 0 bytes Salt*/
+ 32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */
+ NULL, //set below
+ NULL, //set below
+},
+{
+ 24, /* encKeySize: DES-CBC: 24 bytes:NWAL_SA_EALG_3DES_CBC and 0 bytes Salt*/
+ 32, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_SHA2_256 */
NULL, //set below
NULL, //set below
+},
+{
+ 0, /* NWAL_SA_EALG_NULL*/
+ 16, /* NWAL_SA_AALG_HMAC_MD5, 16 bytes */
+ NULL, //set below
+ NULL, //set below
+}
};
-//keys
+
static uint8_t ourAuthKey[36] =
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23 };
-static uint8_t ourEncrKey[36] =
+;
+
+static uint8_t ourEncrKey[36] =
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
- 0x30, 0x31, 0x32, 0x33 };
+ 0x30, 0x31, 0x32, 0x33 };
/*************************END NETAPI OBJECTS***********************/
}
/*-----------test driver: gen an input pkt------- */
//char buffer[sizeof(HEAD_T)+PKT_LEN];
-Ti_Pkt * get_pkt(int n, unsigned int *p_len)
+Ti_Pkt * get_pkt(int n, unsigned int *p_len, Pktlib_HeapHandle heap2use, int size, unsigned char * buf2cpy, int copy_size)
{
int ind;
long long temp;
if (n>=TX_BURST) return NULL; //just gen pkts to warm swtich, so that it knows
//our mac is valid
}
- b=Pktlib_allocPacket(OurHeap,PKT_LEN);
+ b=Pktlib_allocPacket(heap2use,size);
if (!b)
{printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};
//copy test packet into buffer
{
- memcpy(&buffer[0], &testPkt[0],TEST_PKT_LEN);
- *p_len = TEST_PKT_LEN;
+ memcpy(&buffer[0], buf2cpy, copy_size);
+ *p_len = copy_size;
}
return b;
}
-
+static int eof=0;
/*--------------------------------------------------------------
*----------utility to flip a packet and send
*--------------------back to source----------------------------
unsigned char ip_temp[4];
unsigned char new_dest_port[2]={0x75,0x30}; // 30000
uint16_t blah;
+uint16_t i=1; /* for testing only */
+
+uint8_t *p_spi;
+netTestSA_t * p_sa_info;
+uint8_t p_iv[16];
+
+Pktlib_setPacketLen(tip,len);
//mac
memcpy(&mac_temp,&p_pkt[0],6);
memcpy(&p_pkt[0],&p_pkt[6],6);
//outer checksum to 0
if (!flag) memset(&p_pkt[14+10],0,2);
+
+
+
//inner ip &udp for ipsec
if (flag)
{
+ p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]);
+ p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa, (char *)p_spi ,4);
+ if (p_sa_info == NULL)
+ {
+ printf("flip_and_send_pkt(): trie_lookup() failed\n");
+ return;
+ }
//just drop non-udp packet
- if (p_pkt[14+20+8+16+9]!=0x11)
+ if (p_pkt[p_sa_info->tx_payload_info.encOffset+9]!=0x11)
+
{
stats.n_new+=1;Pktlib_freePacket(tip); return;
}
-//spi
-//memset(&p_pkt[14+20],0x88,4);
-//inner ip
-memcpy(&ip_temp, &p_pkt[14+20+8+16+12],4);
-memcpy(&p_pkt[14+20+8+16+12],&p_pkt[14+20+8+16+12+4],4);
-memcpy(&p_pkt[14+20+8+16+12+4],&ip_temp,4);
+memcpy(&ip_temp, &p_pkt[p_sa_info->tx_payload_info.encOffset+12],4);
+memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+12],&p_pkt[p_sa_info->tx_payload_info.encOffset+12+4],4);
+memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+12+4],&ip_temp,4);
//udp
-memcpy(&p_pkt[14+20+8+16+20+2],&new_dest_port[0],2);
-memset(&p_pkt[14+20+8+16+20+6],0,2); //checksum
+memcpy(&p_pkt[p_sa_info->tx_payload_info.encOffset+20+2],&new_dest_port[0],2);
+memset(&p_pkt[p_sa_info->tx_payload_info.encOffset+20+6],0,2); //checksum
-#ifdef IPSEC_MODE_TX_SIDEBAND
-//inner ip checksum : leave alone
+
+
+if (config.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND)
+{
+ //inner ip checksum : leave alone
#if 0
-blah=test_utilOnesCompChkSum (&p_pkt[14+20+8+16], 10);
-p_pkt[14+20+8+16+10]= (blah&0xff00)>>8;
-p_pkt[14+20+8+16+11]= blah&0xff;
+ blah=test_utilOnesCompChkSum (&p_pkt[14+20+8+16], 10);
+ p_pkt[14+20+8+16+10]= (blah&0xff00)>>8;
+ p_pkt[14+20+8+16+11]= blah&0xff;
#endif
-//tbd udp checksum (leave at 0)
+ //tbd udp checksum (leave at 0)
-//outer ip, set to 0 (we will compute on way out
-memset(&p_pkt[14+10],0,2);
-
-#else //inflow, don't touch outer , clear inner
-memset(&p_pkt[14+20+8+16+10],0,2); //inner checksum, we will compute on way out
+ //outer ip, set to 0 (we will compute on way out
+ memset(&p_pkt[14+10],0,2);
+}
+else
+{
+//#else //inflow, don't touch outer , clear inner
+//DALmemset(&p_pkt[14+20+8+16+10],0,2); //inner checksum, we will compute on way out
//outer ip checksum : leave alone
+
#if 0
blah = test_utilOnesCompChkSum (&p_pkt[14], 10);
p_pkt[14+10]= (blah&0xff00)>>8;
p_pkt[14+11]= blah&0xff;
#endif
-#endif
+
+}
}
else
{
//IPSEC case,
if (flag)
{
-#ifdef IPSEC_MODE_TX_SIDEBAND
+ if (config.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND)
//send to crypto for encryption
//12 byte auth tag
{
PKTIO_METADATA_T meta = {PKTIO_META_SB_TX,{0},0};
int err;
nwalDmTxPayloadInfo_t meta_tx={0};
- meta.sa_handle=tx_data_mode_handle; //use TX SA context
+ meta.sa_handle=p_sa_info->tx_data_mode_handle; //use TX SA context
+
+#if 0
meta_tx.ploadLen = len;
- meta_tx.encOffset = 14+20+8+16 ;
- meta_tx.authOffset =14+20 ;
- meta_tx.encSize=len - 14- 20-8-16-12;
- meta_tx.authSize= len -14-20-12;
- meta_tx.encIvSize=16;
- meta_tx.pEncIV= &p_pkt[14+20+8]; //just use same IV..
+
+ meta_tx.encOffset =p_sa_info->tx_payload_info.encOffset;
+
+ meta_tx.authOffset =netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN;
+
+ //meta_tx.encSize=len - 14- 20-8-16-12;
+ meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -netTest_ICV_LEN;
+
+ //meta_tx.authSize= len -14-20-12;
+ meta_tx.authSize = len - meta_tx.authOffset - netTest_ICV_LEN;
+ //meta_tx.encIvSize=16;
+ meta_tx.encIvSize = p_sa_info->tx_payload_info.encIvSize;
+ //meta_tx.pEncIV= &p_pkt[14+20+8]; //just use same IV..
+#endif
+ memcpy(&meta_tx, &(p_sa_info->tx_payload_info), sizeof(nwalDmTxPayloadInfo_t));
+
+ meta_tx.ploadLen = len;
+ meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -netTest_ICV_LEN;
+ meta_tx.authSize = len - meta_tx.authOffset - netTest_ICV_LEN;
+
+ meta_tx.encIvSize = p_sa_info->tx_payload_info.encIvSize;
+#if 0
+ printf("flip_and_send_pkt(): encOffset %d\n", meta_tx.encOffset);
+ printf("flip_and_send_pkt():authOffset %d\n", meta_tx.authOffset);
+ printf("flip_and_send_pkt(): encSize %d\n", meta_tx.encSize);
+ printf("flip_and_send_pkt(): authSize %d\n", meta_tx.authSize);
+ printf("flip_and_send_pkt(): encIvSize %d\n", meta_tx.encIvSize);
+#endif
+
+ if (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CTR)
+ {
+ memcpy(&p_iv[0], &ourEncrKey[16], 4);
+ memcpy(&p_iv[4], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
+ p_iv[12] = 0;
+ p_iv[13] = 0;
+ p_iv[14] = 0;
+ p_iv[15] = 1;
+ meta_tx.pEncIV = &p_iv[0];
+ }
+ else if (p_sa_info->cipherMode == NWAL_SA_EALG_NULL)
+ {
+ meta_tx.pEncIV = NULL;
+ }
+ else
+ {
+ meta_tx.pEncIV = &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN ];
+ }
meta_tx.authIvSize=0;
meta_tx.pAuthIV=NULL;
meta_tx.aadSize=0;
meta_tx.pAad=NULL;
/* post it to netcp sb tx channel*/
+ meta_tx.appCtxId = netapi_timing_start();
meta.u.tx_sb_meta=&meta_tx;
pktio_send(netcp_sb_tx_chan,tip,&meta,&err);
}
-
-#else
+else
{
//inflow tx
//send pkt directly, asking for IP and UDP checksum offloads AND IPSEC to be applied
PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};
int err;
nwalTxPktInfo_t meta_tx={0};
- meta.sa_handle=tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied
- meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_META_DATA_VALID );
- meta_tx.saOffBytes=14+20;
+#define USE_COPY
+#ifdef USE_COPY
+//debug: see if re-using RX descriptor for TX is causing our SA lockup
+{
+ int new_len=0;
+ Ti_Pkt new_tip = get_pkt(0, &new_len, specialLarge , len+10 , &p_pkt[0] , len);
+ if (!new_tip)
+ {
+ printf("net_test> new_tip NULL\n");
+ }
+ else
+ {
+ Pktlib_setPacketLen(new_tip,new_len);
+ Pktlib_freePacket(tip);
+ tip=new_tip;
+ Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&new_len); //reset p_pkt to point to new buffer as its used below
+ Cppi_setTimeStamp (Cppi_DescType_HOST, (Cppi_Desc *) tip,stats.sec_tx);
+ }
+}
+if (len <1500)
+{
+ eof+=1;
+}
+#endif
+ meta.sa_handle=p_sa_info->tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied
+ //meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_META_DATA_VALID );
+ meta_tx.txFlag1 = p_sa_info->tx_pkt_info.txFlag1;
+ meta_tx.enetPort=0;
+ //meta_tx.saOffBytes=14+20;
+ meta_tx.saOffBytes= p_sa_info->tx_pkt_info.saOffBytes;
meta_tx.saPayloadLen=len-14-20; //don't include tag, mac and outer header
- meta_tx.startOffset = 0;
- meta_tx.ipOffBytes = 14+20+8+16; //to inner header
- meta_tx.l4OffBytes = 14+20+8+16+20; //to L4
- meta_tx.l4HdrLen = 8;
- meta_tx.ploadLen = (unsigned) ((p_pkt[14+20+8+16+20+4]<<8)|p_pkt[14+20+8+16+20+4+1]) -8 ;
+ //meta_tx.startOffset = 0;
+ meta_tx.startOffset = p_sa_info->tx_pkt_info.startOffset;
+ //meta_tx.ipOffBytes = 14+20+8+16; //to inner header
+ meta_tx.ipOffBytes =p_sa_info->tx_payload_info.encOffset;
+ //meta_tx.l4OffBytes = 14+20+8+16+20; //to L4
+ meta_tx.l4OffBytes = p_sa_info->tx_pkt_info.l4OffBytes;
+ meta_tx.l4HdrLen = p_sa_info->tx_pkt_info.l4HdrLen;
+ meta_tx.ploadLen = (unsigned) ((p_pkt[meta_tx.l4OffBytes+4]<<8)|p_pkt[meta_tx.l4OffBytes+4+1]) -8 ;
meta_tx.pseudoHdrChecksum =
- test_utilGetIpv4PsudoChkSum(&p_pkt[14+20+8+16],8+ meta_tx.ploadLen);
+ test_utilGetIpv4PsudoChkSum(&p_pkt[meta_tx.ipOffBytes],8+ meta_tx.ploadLen);
/* post it to netcp tx channel*/
meta.u.tx_meta=&meta_tx;
+ if (stats.sec_tx<20) dump_descr((long *) tip, stats.sec_tx);
pktio_send(netcp_tx_chan,tip,&meta,&err);
stats.tx +=1;
stats.sec_tx +=1;
}
-#endif
-
-
}
else //non ipsec send pkt directly, asking for IP and UDP checksum ofload
{
HEAD_T temp_head;
int tag_cmp=0;
unsigned int hash[3];
+uint8_t *p_spi;
+netTestSA_t *p_sa_info;
+//nwal_AppId time;
+unsigned long time, delta_time;
/* loop over received pkts */
for(i=0;i<n_pkts;i++)
{
Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
len = Pktlib_getPacketLen(tip);//real length
+
+ p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]);
+ p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa, (char *)p_spi ,4);
+ if (p_sa_info == NULL)
+ {
+ printf("recv_sb_cb(): trie_lookup failed\n");
+ continue;
+ }
+
+
//is this a decrypt (rx_tunnel) complete
- if ((int)meta[i].u.rx_sb_meta->appId == rx_tunnel)
+ if ((int)meta[i].u.rx_sb_meta->appId == p_sa_info->rx_tunnel)
{
- stats.sb_rx+=1;
+
+ time = netapi_timing_start();
+ delta_time = time -(unsigned long) meta[i].u.rx_sb_meta->appCtxId;
+ stats.total_decrypt_time += delta_time;
+ stats.sb_rx+=1;
//copy hash out of meta data (for some reason it needs endian conversion)
hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
if(stats.sb_rx<=16)
{
char *tp = (char *) &hash[0];
- dump_header((long*)p_pkt, stats.sb_rx, (int)meta[i].u.rx_sb_meta->appId,0);
+ //dump_header((long*)p_pkt, stats.sb_rx, (int)meta[i].u.rx_sb_meta->appId,0);
+#if 0
printf("tag in pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n",
p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],
p_pkt[len-7],p_pkt[len-6],
printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n",
tp[0],tp[1],tp[2],tp[3],tp[4],tp[5],
tp[6],tp[7],tp[8],tp[9],tp[10],tp[11]);
+#endif
}
//check tag
tag_cmp = memcmp(&p_pkt[len-12],(char*) &hash[0],12); //todo, really use meta->authTagLen
stats.n_auth_ok += !(tag_cmp);
- flip_and_send_pkt(tip, p_pkt, len,1); //flip packet to echo back and send
+
+ flip_and_send_pkt(tip, p_pkt, len,1); //flip packet to echo back and send
}
//this is an encrypt (tx tunnel) complete
- else if((int)meta[i].u.rx_sb_meta->appId== tx_tunnel )
+ else if((int)meta[i].u.rx_sb_meta->appId== p_sa_info->tx_tunnel )
{
hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
if(stats.sb_tx<=16)
{
char *tp1 = (char *) &hash[0];
- dump_header((long*)p_pkt, stats.sb_tx, (int)meta[i].u.rx_sb_meta->appId,0);
+ //dump_header((long*)p_pkt, stats.sb_tx, (int)meta[i].u.rx_sb_meta->appId,0);
+#if 0
printf("tag in original rx pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n",
p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],
p_pkt[len-7],p_pkt[len-6],
printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n",
tp1[0],tp1[1],tp1[2],tp1[3],tp1[4],tp1[5],
tp1[6],tp1[7],tp1[8],tp1[9],tp1[10],tp1[11]);
+#endif
}
//put the computed tag in the packet
memcpy(&p_pkt[len-12],(char*)&hash[0],12); //todo, really use meta->authTagLen
meta2.sa_handle=nwal_HANDLE_INVALID;
meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID);//only outer IP header checksum. no udp checksum possible since pkt is already encrypted
meta_tx.startOffset = 0;
- meta_tx.ipOffBytes = 14;
+ meta_tx.ipOffBytes = netTest_MAC_HEADER_LEN;
//not used
meta_tx.l4OffBytes = 0;
meta_tx.l4HdrLen = 0;
meta_tx.ploadLen = 0;
+ time = netapi_timing_start();
+ delta_time = time -(unsigned long) meta[i].u.rx_sb_meta->appCtxId;
+ stats.total_encrypt_time += delta_time;
+
/* post it to netcp tx channel*/
meta2.u.tx_meta=&meta_tx;
char * p_pkt;
HEAD_T * p_head;
HEAD_T temp_head;
+netTestSA_t *p_sa_info;
+uint8_t *p_spi;
+uint8_t p_iv[16];
p_head=&temp_head;
//test_alloc_free(7);
//printf("recv start\n");
- /* loop over received pkts */
- for(i=0;i<n_pkts;i++)
+ /* loop over received pkts */
+ for(i=0;i<n_pkts;i++)
{
- tip = p_recv[i];
- Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
- len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
+ tip = p_recv[i];
+ Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
+ len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
- //debug: validate descriptor */
- if(Pktlib_getNextPacket(tip) != 0) {printf(" rcv_cb, nexpkt != NULL");}
+ //debug: validate descriptor */
+ if(Pktlib_getNextPacket(tip) != 0)
+ {
+ printf(" rcv_cb, nexpkt != NULL");
+ }
//debug printf("recv pkt, len=%d %d\n", len, templen);
- stats.rx+=1;
+ stats.rx+=1;
#ifdef DEBUG_DESC
- if (stats.rx<16){printf(">rx dmp.."); dump_descr((long *) tip, stats.rx);}
- else if (stats.rx>99) {printf(">rx dmp.."); dump_descr((long *) tip,stats.rx);}
+ if (stats.rx<16)
+ {
+ printf(">rx dmp..");
+ dump_descr((long *) tip, stats.rx);
+ }
+ else if (stats.rx>99)
+ {
+ printf(">rx dmp..");
+ dump_descr((long *) tip,stats.rx);
+ }
#endif
- if(stats.rx<=16)
- {
- dump_header((long*)p_pkt, stats.rx, (int)meta[i].u.rx_meta->appId,meta[i].u.rx_meta->rxFlag1);
- }
- /* check header */
- memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
+#if 0
+ if(stats.rx<=16)
+ {
+ dump_header((long*)p_pkt, stats.rx, (int)meta[i].u.rx_meta->appId,meta[i].u.rx_meta->rxFlag1);
+ }
+#endif
+ /* check header */
+ memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
if ((p_head->ip[2]&0x0000ff00)==0x00003200)
{
- if (!check_header(p_head,&meta[i])) {
- stats.n_bad+=1;Pktlib_freePacket(tip); continue;
- }
-
- //process IP SEC PACKET
-#ifdef IPSEC_MODE_RX_SIDEBAND
+ if (!check_header(p_head,&meta[i]))
+ {
+ stats.n_bad+=1;Pktlib_freePacket(tip);
+ continue;
+ }
+
+
+
+
+ //process IP SEC PACKET
+ if (config.ipsec_mode_rx == IPSEC_MODE_RX_SIDEBAND)
{
+ p_spi = &(p_pkt[netTest_MAC_HEADER_LEN+netTest_IP_HEADER_LEN]);
+ p_sa_info = (netTestSA_t *) trie_lookup(p_trie_sa, (char *)p_spi ,4);
+ if (p_sa_info == NULL)
+ {
+ printf("recv_cb(): trie_lookup() failed\n");
+ continue;
+ }
//ship to crypto for decrypt!!
//12 byte auth tag
- PKTIO_METADATA_T meta2 = {PKTIO_META_SB_TX,{0},0};
+ PKTIO_METADATA_T meta2 = {PKTIO_META_SB_TX,{0},0};
nwalDmTxPayloadInfo_t meta_tx={0};
- meta2.sa_handle=rx_data_mode_handle;
+ meta2.sa_handle=p_sa_info->rx_data_mode_handle;
+
+ memcpy(&meta_tx, &(p_sa_info->tx_payload_info), sizeof(nwalDmTxPayloadInfo_t));
+
meta_tx.ploadLen = len;
- meta_tx.encOffset = 14+20+8+16 ;
- meta_tx.authOffset =14+20 ;
- meta_tx.encSize=len - 14- 20-8-16-12;
- meta_tx.authSize= len -14-20-12;
- meta_tx.encIvSize=16;
- meta_tx.pEncIV= &p_pkt[14+20+8];
- meta_tx.authIvSize=0;
- meta_tx.pAuthIV=NULL;
- meta_tx.aadSize=0;
- meta_tx.pAad=NULL;
+ meta_tx.encSize = len - p_sa_info->tx_payload_info.encOffset -netTest_ICV_LEN;
+ meta_tx.authSize = len - meta_tx.authOffset - netTest_ICV_LEN;
+
+ meta_tx.encIvSize = p_sa_info->tx_payload_info.encIvSize;
+#if 0
+ printf("recv_cb(): encOffset %d\n", meta_tx.encOffset);
+ printf("recv_cb():authOffset %d\n", meta_tx.authOffset);
+ printf("recv_cb(): encSize %d\n", meta_tx.encSize);
+ printf("recv_cb(): authSize %d\n", meta_tx.authSize);
+ printf("recv_cb(): encIvSize %d\n", meta_tx.encIvSize);
+#endif
+
+ if (p_sa_info->cipherMode == NWAL_SA_EALG_AES_CTR)
+ {
+ memcpy(&p_iv[0], &ourEncrKey[16], 4);
+ memcpy(&p_iv[4], &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN], 8);
+ p_iv[12] = 0;
+ p_iv[13] = 0;
+ p_iv[14] = 0;
+ p_iv[15] = 1;
+ meta_tx.pEncIV = &p_iv[0];
+ }
+ else if (p_sa_info->cipherMode == NWAL_SA_EALG_NULL)
+ {
+ meta_tx.pEncIV = NULL;
+ }
+ else
+ {
+ meta_tx.pEncIV = &p_pkt[netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN + netTest_ESP_HEADER_LEN ];
+ }
+ meta_tx.appCtxId = netapi_timing_start();
+ //printf("recv_cb appCtxId: %lu\n", meta_tx.appCtxId);
+
/* post it to netcp sb tx channel*/
meta2.u.tx_sb_meta=&meta_tx;
pktio_send(netcp_sb_tx_chan,tip,&meta2,&err);
continue;
}
-#else
- //inflow mode. flip and send
- flip_and_send_pkt(tip,p_pkt,len,1);
-#endif
+ else
+ //inflow mode. flip and send
+ flip_and_send_pkt(tip,p_pkt,len,1);
}
else if ((p_head->ip[2]&0x0000ff00)!=0x00001100)
{
- stats.n_new+=1;Pktlib_freePacket(tip); continue;
+ stats.n_new+=1;Pktlib_freePacket(tip); continue;
}
else //non ipsec
{
if (!check_header(p_head,&meta[i])) {
- stats.n_bad+=1;Pktlib_freePacket(tip); continue;
+ stats.n_bad+=1;Pktlib_freePacket(tip);
+ continue;
}
#if 0
/* update_mac(&p_pkt[0]); */
/* 'simulate' send pkt */
- send_pkt(tip,len);
+ send_pkt(tip,len);
#endif
- //just flip and send
- flip_and_send_pkt(tip,p_pkt,len,0);
+ //just flip and send
+ flip_and_send_pkt(tip,p_pkt,len,0);
+ }
}
- }
//printf("recv done\n");
}
}
}
+void print_ipsec_stats(Sa_IpsecStats_t *p_saIpsecStats, nwal_saAALG auth, nwal_saEALG cipher)
+{
+#if 0
+ if(retVal != nwal_OK)
+ {
+ System_printf("CORE: %d Error getting IP Sec Stats: Ret Status: %d \n",
+ retVal);
+ return(nwal_FALSE);
+ }
+ if((p_saIpsecStats->pktEncHi) ||(p_saIpsecStats->pktEncLo))
+ {
+ printf("------------- IPSec TX (Encryption Channel) Stats BEGIN --\n");
+ }
+ else
+ {
+ printf("------------- IPSec RX (Decryption Channel) Stats BEGIN --\n");
+ }
+#endif
+ printf("\nAutentication mode: %d, Encryption Mode: %d\n", auth, cipher);
+ printf("IPSec replayOld:0x%x,replayDup:0x%x,authFail:0x%x \n",
+ p_saIpsecStats->replayOld,p_saIpsecStats->replayDup,p_saIpsecStats->authFail);
+ printf("IPSec txESN:0x%x,rxESN:0x%x,pktEncHi:0x%x,pktEncLo:0x%x,pktDecHi:0x%x,pktDecLo:0x%x \n",
+ p_saIpsecStats->txESN,p_saIpsecStats->rxESN,p_saIpsecStats->pktEncHi,
+ p_saIpsecStats->pktEncLo,p_saIpsecStats->pktDecHi,p_saIpsecStats->pktDecLo);
+ printf("------------- IPSec Stats END ----------------------------\n\n");
+}
+
+void print_datamode_stats(Sa_DataModeStats_t *p_saDataModeStats, nwal_saAALG auth, nwal_saEALG cipher)
+{
+
+ printf("\nAutentication mode: %d, Encryption Mode: %d\n", auth, cipher);
+ printf(" Packets processedHi: 0x%x, Packets processed Lo:0x%x\n",
+ p_saDataModeStats->pktHi, p_saDataModeStats->pktLo);
+}
+
+
+
static int np2process = NP;
/******************************************************
uint32_t numZeroBufferPackets;
uint32_t numPacketsinGarbage;
Pktlib_HeapStats pktLibHeapStats;
+int i;
+unsigned long long bcpp;
+unsigned long long bcpp_noc;
+unsigned long long bcpp_app;
+unsigned long long bcpp_tx;
+unsigned long long npL;
+unsigned long long cyclesL;
+unsigned long long ccyclesL; //cache cycles
+NETAPI_SA_STATS_T netapi_sa_stats;
printf(">*****stats @ %lld\n", netapi_getTimestamp());
//printf("netcp_tx_handle check %x\n", netcp_tx_chan->back);
-printf(">itx=%d rx=%d tx=%d bad=%d slow=%d \n>rx_class0=%d rx_class1=%d rx_class2=%d secRx=%d secPRX=%d sb_rx=%d sb_tx=%d auth_ok=%d\n n_t1=%d n_t2=%d n_t3=%d\n",stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new,
+printf(">itx=%d rx=%d tx=%d bad=%d slow=%d \n>rx_class0=%d rx_class1=%d rx_class2=%d secRx=%d secPRX=%d sb_rx=%d sb_tx=%d auth_ok=%d sec_tx=%d\n",
+ stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new,
stats.n_class0_rx, stats.n_class1_rx,
stats.n_class2_rx, stats.sec_rx, stats.secp_rx, stats.sb_rx, stats.sb_tx, stats.n_auth_ok,
- stats.n_t1, stats.n_t2,stats.n_t3);
-
+ stats.sec_tx);
+
+if (stats.rx && stats.tx)
+ printf("decrypt time per packet(avg): %lu, encrypt time per packet(avg): %lu\n",
+ (unsigned long) stats.total_decrypt_time/stats.rx, (unsigned long) stats.total_encrypt_time/stats.tx);
+netapi_sched_get_stats(&npL,&cyclesL,&ccyclesL);
+if (npL && stats.rx) {
+ bcpp = cyclesL/npL;
+ bcpp_noc = (cyclesL-ccyclesL)/npL;
+ bcpp_app = (stats.app_cycles-stats.tx_cache_cycles)/stats.rx;
+}
+else {bcpp = bcpp_noc=bcpp_app=0L;}
+if (stats.tx)
+{
+ bcpp_tx = (stats.send_cycles-stats.tx_cache_cycles)/stats.tx;
+}else {bcpp_tx = 0L;}
+printf("> ++ busy cycles pp=%lld (%lld wo cache ops) (app+tx= %lld) (tx= %lld) ++\n",
+ bcpp,bcpp_noc,bcpp_app, bcpp_tx);
if(pPaStats)
{
printf("C1 number of packets: %d\n", pPaStats->classify1.nPackets);
pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
+#if 0
+printf("pa2sa descriptor area dump\n");
+for(i=0;i<TUNE_NETAPI_CONFIG_MAX_PA_TO_SA_DESC;i++)
+{
+ extern long * pa2sa_descr_base;
+ long * tip= &pa2sa_descr_base[32*i];
+ dump_descr(tip, i);
+}
+printf("sa2pa descriptor area dump\n");
+for(i=0;i<TUNE_NETAPI_CONFIG_MAX_SA_TO_PA_DESC;i++)
+{
+ extern long * sa2pa_descr_base;
+ long * tip= &sa2pa_descr_base[32*i];
+ dump_descr(tip, i);
+}
+#endif
//debug = dump timer polling stats
-dump_poll_stats();
+//dump_poll_stats();
+ for (i = 0; i < MAX_SEC_INDEX; i++)
+ {
+ if (config.ipsec_mode_rx == IPSEC_MODE_RX_INFLOW)
+ {
+ memset(&netapi_sa_stats, 0, sizeof(netapi_sa_stats));
+ netapi_getSaStats(netapi_handle, sa_info[i].rx_tunnel, &netapi_sa_stats);
+ if (netapi_sa_stats.mode_active & NETAPI_INFLOW_MODE_ACTIVE)
+ print_ipsec_stats(&(netapi_sa_stats.saIpsecStats), rx_sa[i].authMode, rx_sa[i].cipherMode);
+ }
+#if 0
+ else
+ {
+ memset(&netapi_sa_stats, 0, sizeof(netapi_sa_stats));
+ netapi_getSaStats(netapi_handle, sa_info[i].rx_tunnel, &netapi_sa_stats);
+ if (netapi_sa_stats.mode_active & NETAPI_SIDEBAND_MODE_ACTIVE)
+ print_datamode_stats(&(netapi_sa_stats.dataModeStats),rx_sa[i].authMode, rx_sa[i].cipherMode);
+ }
+#endif
+ if (config.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
+ {
+ memset(&netapi_sa_stats, 0, sizeof(netapi_sa_stats));
+ netapi_getSaStats(netapi_handle, sa_info[i].tx_tunnel, &netapi_sa_stats);
+ if (netapi_sa_stats.mode_active & NETAPI_INFLOW_MODE_ACTIVE)
+ print_ipsec_stats(&(netapi_sa_stats.saIpsecStats), tx_sa[i].authMode, tx_sa[i].cipherMode);
+ }
+#if 0
+ else
+ {
+ memset(&netapi_sa_stats, 0, sizeof(netapi_sa_stats));
+ netapi_getSaStats(netapi_handle, sa_info[i].tx_tunnel, &netapi_sa_stats);
+ if (netapi_sa_stats.mode_active & NETAPI_SIDEBAND_MODE_ACTIVE)
+ print_datamode_stats(&(netapi_sa_stats.dataModeStats),tx_sa[i].authMode, tx_sa[i].cipherMode);
+ }
+ #endif
+
+ }
}
//******************************************************
//use scheduling housekeeping callback to generate pkts
//******************************************************
+static int done_burst=0;
void house(NETAPI_SCHED_HANDLE_T * s)
{
Ti_Pkt * tip;
unsigned int len;
-nwalTxPktInfo_t meta_tx;
+nwalTxPktInfo_t meta_tx = {0};
PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};
int err;
static int house_pkts_gened=0;
static int first =0;
Cppi_HostDesc* pPktDesc;
+if(done_burst)
+{
+ house_pkts_gened+=TX_BURST;
+ 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)
+ {
+ netapi_schedShutdown(s,NULL,&err);
+ }
+ return;
+}
+done_burst=1;
Osal_cache_op_measure_reset();
memset(&meta_tx,0,sizeof(meta_tx));
for(p=0;p<TX_BURST;p++) {
/* manufacture a pkt to transmit */
- tip = get_pkt(house_pkts_gened, &len);
+ tip = get_pkt(house_pkts_gened, &len, OurHeap, PKT_LEN,&testPkt[0] , TEST_PKT_LEN);
if(!tip) { house_pkts_gened +=1; continue; }
meta_tx.ploadLen = TEST_PAYLOAD_LEN;
Pktlib_getDataBuffer(tip,&pData,&len);
+ if(house_pkts_gened &0x1)
+ {
+ memcpy(&pData[6],&config.mac1[0] ,6);
+ }
pIpHdr = pData + meta_tx.ipOffBytes;
meta_tx.pseudoHdrChecksum =
test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));
#else
+ Pktlib_getDataBuffer(tip,&pData,&len);
+ if(house_pkts_gened &0x1)
+ {
+ memcpy(&pData[6],&config.mac1[0] ,6);
+ }
meta_tx.txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID;
meta_tx.startOffset = 0;
meta_tx.ploadLen = TEST_PAYLOAD_LEN;
}
}
+void build_sa_db(int i)
+{
+
+ if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_SHA1) && (tx_sa[i].cipherMode == NWAL_SA_EALG_AES_CBC))
+ {
+ /* static configuration, will not change */
+ sa_info[i].tx_payload_info.aadSize = 0;
+ sa_info[i].tx_payload_info.pAad = NULL;
+ sa_info[i].tx_payload_info.authIvSize = 0;
+ sa_info[i].tx_payload_info.pAuthIV = NULL;
+ sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN; /*done: same for all cipher suites */
+ sa_info[i].tx_payload_info.encIvSize = netTest_AES_CBC_IV_LEN;
+ sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN +
+ netTest_IP_HEADER_LEN +
+ netTest_ESP_HEADER_LEN +
+ netTest_AES_CBC_IV_LEN;
+
+
+
+ /* dynamic configuration, will be calculated on the fly */
+ sa_info[i].tx_payload_info.authSize = 0; /* pkt len - mac - ip -icv (12) */
+ sa_info[i].tx_payload_info.encSize = 0; /* authSize - esp header size (always 8 bytes) */
+ sa_info[i].tx_payload_info.ploadLen = 0; /* will be packet length */
+ sa_info[i].tx_payload_info.pEncIV = 0;
+ sa_info[i].tx_payload_info.pPkt = 0; /* not being referenced in net_test */
+
+ sa_info[i].cipherMode = NWAL_SA_EALG_AES_CBC;
+ sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
+ sa_info[i].auth_tag_size = netTest_ICV_LEN; /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
+#ifdef EXPERIMENTAL
+ sa_info[i].iv_len=16;
+ sa_info[i].bl=16;
+ sa_info[i].spi = tx_sa[i].spi;
+ sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
+ sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
+#endif
+ sa_info[i].tx_pkt_info.enetPort = 0;
+ sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
+ sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
+ sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
+ sa_info[i].tx_pkt_info.startOffset = 0;
+ sa_info[i].tx_pkt_info.lpbackPass = 0;
+ sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
+ sa_info[i].tx_pkt_info.pPkt = NULL;
+ sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN;
+ sa_info[i].tx_pkt_info.saPayloadLen = 0;
+ sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
+
+ sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
+
+ trie_insert(p_trie_sa,(char *)&(tx_sa[i].spi),4, (void *) &sa_info[i]); //asociate with tx sa SPI
+
+ }
+ else if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_SHA2_256) && (tx_sa[i].cipherMode == NWAL_SA_EALG_AES_CTR))
+ {
+ printf("inside build_sa_db, index %d\n", i);
+ /* static configuration, will not change */
+ sa_info[i].tx_payload_info.aadSize = 0;
+ sa_info[i].tx_payload_info.pAad = NULL;
+ sa_info[i].tx_payload_info.authIvSize = 0;
+ sa_info[i].tx_payload_info.pAuthIV = NULL;
+ sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN; /*done: same for all cipher suites */
+ sa_info[i].tx_payload_info.encIvSize = netTest_AES_CTR_IV_CONTEXT_LEN;
+ sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN +
+ netTest_IP_HEADER_LEN +
+ netTest_ESP_HEADER_LEN +
+ netTest_AES_CTR_IV_PACKET_LEN;
+
+
+
+
+ /* dynamic configuration, will be calculated on the fly */
+ sa_info[i].tx_payload_info.authSize = 0;
+ sa_info[i].tx_payload_info.encSize = 0;
+ sa_info[i].tx_payload_info.ploadLen = 0;
+ sa_info[i].tx_payload_info.pEncIV = 0;
+ sa_info[i].tx_payload_info.pPkt = 0;
+
+ sa_info[i].cipherMode = NWAL_SA_EALG_AES_CTR;
+ sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
+ sa_info[i].auth_tag_size = netTest_ICV_LEN; /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
+#ifdef EXPERIMENTAL
+ sa_info[i].iv_len=8;
+ sa_info[i].bl=8;
+ sa_info[i].spi = tx_sa[i].spi;
+ sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
+ sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
+#endif
+
+ sa_info[i].tx_pkt_info.enetPort = 0;
+ sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
+ sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
+ sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
+ sa_info[i].tx_pkt_info.startOffset = 0;
+ sa_info[i].tx_pkt_info.lpbackPass = 0;
+ sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
+ sa_info[i].tx_pkt_info.pPkt = NULL;
+ sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN;
+ sa_info[i].tx_pkt_info.saPayloadLen = 0;
+ sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
+
+ sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
+
+ trie_insert(p_trie_sa,(char *)&(tx_sa[i].spi),4, (void *) &sa_info[i]); //asociate with tx sa SPI
+ }
+ else if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_SHA2_256) && (tx_sa[i].cipherMode == NWAL_SA_EALG_3DES_CBC))
+ {
+ /* static configuration, will not change */
+ sa_info[i].tx_payload_info.aadSize = 0;
+ sa_info[i].tx_payload_info.pAad = NULL;
+ sa_info[i].tx_payload_info.authIvSize = 0;
+ sa_info[i].tx_payload_info.pAuthIV = NULL;
+ sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN; /*done: same for all cipher suites */
+ sa_info[i].tx_payload_info.encIvSize = netTest_3DES_CBC_IV_LEN;
+ sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN +
+ netTest_IP_HEADER_LEN +
+ netTest_ESP_HEADER_LEN +
+ netTest_3DES_CBC_IV_LEN;
+
+ /* dynamic configuration, will be calculated on the fly */
+ sa_info[i].tx_payload_info.authSize = 0;
+ sa_info[i].tx_payload_info.encSize = 0;
+ sa_info[i].tx_payload_info.ploadLen = 0;
+ sa_info[i].tx_payload_info.pEncIV = 0;
+ sa_info[i].tx_payload_info.pPkt = 0;
+
+ sa_info[i].cipherMode = NWAL_SA_EALG_3DES_CBC;
+ sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
+ sa_info[i].auth_tag_size = netTest_ICV_LEN; /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
+#ifdef EXPERIMENTAL
+ sa_info[i].iv_len=8;
+ sa_info[i].bl=8;
+ sa_info[i].spi = tx_sa[i].spi;
+ sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
+ sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
+#endif
+
+ sa_info[i].tx_pkt_info.enetPort = 0;
+ sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
+ sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
+ sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
+ sa_info[i].tx_pkt_info.startOffset = 0;
+ sa_info[i].tx_pkt_info.lpbackPass = 0;
+ sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
+ sa_info[i].tx_pkt_info.pPkt = NULL;
+ sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN;
+ sa_info[i].tx_pkt_info.saPayloadLen = 0;
+ sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
+
+ sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
+
+ trie_insert(p_trie_sa,(char *)&(tx_sa[i].spi),4, (void *) &sa_info[i]); //asociate with tx sa SPI
+ }
+ else if ((tx_sa[i].authMode == NWAL_SA_AALG_HMAC_MD5) && (rx_sa[i].cipherMode == NWAL_SA_EALG_NULL))
+ {
+ /* static configuration, will not change */
+ sa_info[i].tx_payload_info.aadSize = 0;
+ sa_info[i].tx_payload_info.pAad = NULL;
+ sa_info[i].tx_payload_info.authIvSize = 0;
+ sa_info[i].tx_payload_info.pAuthIV = NULL;
+ sa_info[i].tx_payload_info.authOffset = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN; /*done: same for all cipher suites */
+ sa_info[i].tx_payload_info.encIvSize = netTest_NULL_IV_LEN;
+
+ sa_info[i].tx_payload_info.encOffset = netTest_MAC_HEADER_LEN +
+ netTest_IP_HEADER_LEN +
+ netTest_ESP_HEADER_LEN +
+ netTest_NULL_IV_LEN;
+#ifdef EXPERIMENTAL
+ sa_info[i].iv_len=0;
+ sa_info[i].bl=4;
+ sa_info[i].spi = tx_sa[i].spi;
+ sa_info[i].src =*((unsigned int *)(&config.local_ipsec_ip.ipv4[0]));
+ sa_info[i].dst =*((unsigned int *)(&config.remote_ipsec_ip.ipv4[0]));
+#endif
+
+
+ /* dynamic configuration, will be calculated on the fly */
+ sa_info[i].tx_payload_info.authSize = 0;
+ sa_info[i].tx_payload_info.encSize = 0;
+ sa_info[i].tx_payload_info.ploadLen = 0;
+ sa_info[i].tx_payload_info.pEncIV = 0;
+ sa_info[i].tx_payload_info.pPkt = 0;
+
+ sa_info[i].cipherMode = NWAL_SA_EALG_NULL;
+ sa_info[i].inner_ip_offset = sa_info[i].tx_payload_info.encOffset;
+ sa_info[i].auth_tag_size = netTest_ICV_LEN; /* icv or mac size,. always 12 except for AES_CCM/AES_GCM */
+
+ sa_info[i].tx_pkt_info.enetPort = 0;
+ sa_info[i].tx_pkt_info.ipOffBytes = sa_info[i].tx_payload_info.encOffset;
+ sa_info[i].tx_pkt_info.l4HdrLen = netTest_UDP_HEADER_LEN; /*UDP header len */
+ sa_info[i].tx_pkt_info.l4OffBytes = sa_info[i].inner_ip_offset + netTest_IP_HEADER_LEN;
+ sa_info[i].tx_pkt_info.startOffset = 0;
+ sa_info[i].tx_pkt_info.lpbackPass = 0;
+ sa_info[i].tx_pkt_info.ploadLen = 0; /*sa_info[i].tx_pkt_info.l4OffBytes + 4 */
+ sa_info[i].tx_pkt_info.pPkt = NULL;
+ sa_info[i].tx_pkt_info.saOffBytes = netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN;
+ sa_info[i].tx_pkt_info.saPayloadLen = 0;
+ sa_info[i].tx_pkt_info.pseudoHdrChecksum =0;
+
+ sa_info[i].tx_pkt_info.txFlag1 = NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID ;
+
+ trie_insert(p_trie_sa,(char *)&(tx_sa[i].spi),4, (void *) &sa_info[i]); //asociate with tx sa SPI
+ }
+ else
+ printf("build_sa_db(): invalid encryption/authentication combination selected\n");
+
+ //printf("sa_build_db(): authOffset %d, innerIpOffset %d, encOffset %d\n", sa_info[i].tx_payload_info.authOffset, sa_info[i].inner_ip_offset, sa_info[i].tx_payload_info.encOffset);
+
+
+}
+
+
+
+#define CHECK_SET_PARAM(ARG1, ARG2) \
+ do { \
+ if(strcmp(key, ARG1) == 0) { \
+ if(data)strncpy(ARG2,data,CONFIG_STRING_LEN); \
+ printf("CHECK_SET_PARM, match found, input cong string %s\n", ARG2); \
+ continue; \
+ } \
+ } while(0)
+
+#define CHECK_SET_PARAM2(ARG1, ARG2, ARG3) \
+ do { \
+ if(strcmp(key, ARG1) == 0) { \
+ if(data) strncpy(ARG2,data,CONFIG_STRING_LEN); \
+ if(data2) strncpy(ARG3,data2,CONFIG_STRING_LEN); \
+ printf("CHECK_SET_PARM, match found, input cong string %s %s\n", ARG2, ARG3); \
+ continue; \
+ } \
+ } while(0)
+
+unsigned char hex2dec(char *p_s)
+{
+ int val;
+ sscanf(p_s,"%x",&val);
+ return val&0xff;
+}
+void parse_one_mac(char * p_mac_str, unsigned char *p_mac)
+{
+ int index = 0;
+ int i;
+ char *pch = strtok (&(p_mac_str[0]),"-");
+
+ while (pch != NULL)
+ {
+ printf ("%s\n",pch);
+ p_mac[index] = hex2dec(pch);
+ index++;
+ pch = strtok (NULL,"-");
+ }
+ printf("index value : %d\n", index);
+ for (i=0; i<6;i++)
+ printf("************mac0[%d]: 0x%x\n",i, p_mac[i]);
+}
+
+void parse_one_ip(char * p_ip_addr_str, unsigned char * p_ip)
+{
+ int index = 0;
+ int i;
+ char * pch = strtok (&p_ip_addr_str[0],".");
+
+ while (pch != NULL)
+ {
+ printf ("xxxxx: %s\n",pch);
+ p_ip[index] = atoi(pch);
+ index++;
+ pch = strtok (NULL,".");
+ }
+ printf("index value : %d\n", index);
+ for (i=0; i<4;i++)
+ printf("************ip[%d]: 0x%x\n",i, p_ip[i]);
+
+
+}
+
+void parse_mac_address(netTestConfigFile_t *pConfig)
+{
+ if (strlen(&pConfig->mac0[0]))
+ parse_one_mac(&pConfig->mac0[0],&config.mac0[0]);
+ if (strlen(&pConfig->mac1[0]))
+ parse_one_mac(&pConfig->mac1[0],&config.mac1[0]);
+}
+void parse_ip_address(netTestConfigFile_t *pConfig)
+{
+ if (strlen(&pConfig->ip0[0]))
+ parse_one_ip(&pConfig->ip0[0],&config.ip0.ipv4[0]);
+ if (strlen(&pConfig->ip1[0]))
+ parse_one_ip(&pConfig->ip1[0],&config.ip1.ipv4[0]);
+ if (strlen(&pConfig->ip2[0]))
+ parse_one_ip(&pConfig->ip2[0],&config.ip2.ipv4[0]);
+ if (strlen(&pConfig->local_ipsec_ip[0]))
+ parse_one_ip(&pConfig->local_ipsec_ip[0],&config.local_ipsec_ip.ipv4[0]);
+ if (strlen(&pConfig->remote_ipsec_ip[0]))
+ parse_one_ip(&pConfig->remote_ipsec_ip[0],&config.remote_ipsec_ip.ipv4[0]);
+}
+
+
+void parse_ipsec_mode(netTestConfigFile_t *pConfig)
+{
+
+ printf("parse_ipsec_mode, string length %d\n", strlen(&pConfig->ipsec_mode_rx));
+ if (strlen(&pConfig->ipsec_mode_rx[0]))
+ {
+ if (strcmp(pConfig->ipsec_mode_rx, "SIDEBAND") == 0)
+ {
+ config.ipsec_mode_rx = IPSEC_MODE_RX_SIDEBAND;
+ }
+ else if (strcmp(pConfig->ipsec_mode_rx, "INFLOW") == 0)
+ {
+ config.ipsec_mode_rx = IPSEC_MODE_RX_INFLOW;
+ }
+ else
+ printf("parse_ipsec_mode(), invalid RX ipsec mode in config file \n");
+ }
+
+ if (strlen(&pConfig->ipsec_mode_tx[0]))
+ {
+ if (strcmp(pConfig->ipsec_mode_tx, "SIDEBAND") == 0)
+ {
+ config.ipsec_mode_tx = IPSEC_MODE_TX_SIDEBAND;
+ }
+ else if (strcmp(pConfig->ipsec_mode_tx, "INFLOW") == 0)
+ {
+ config.ipsec_mode_tx = IPSEC_MODE_TX_INFLOW;
+ }
+ else
+ printf("parse_ipsec_mode(), invalid TX ipsec mode in config file \n");
+ }
+
+ printf("parse_ipsec_mode(): RX mode %d\n", config.ipsec_mode_rx);
+ printf("parse_ipsec_mode(): TX mode %d\n", config.ipsec_mode_tx);
+
+
+}
+
+#ifdef EXPERIMENTAL
+int n_routes=0;
+int n_dst_ips=0;
+void parse_routes(netTestConfigFile_t *pConfig)
+{
+int i;
+int said=0;
+for(i=0;i<MAX_ROUTES;i++)
+{
+ int port;
+ if (pConfig->routes[i][0])
+ {
+ port=atoi(&pConfig->ports[i][0]);
+ if((port<1)||(port>2)) continue; //bad port #: only 1 or 2 valid
+ if(strncmp(&pConfig->routes[i][0],"MAC",3)==0)
+ {
+ routes[i].out_port = port;
+ parse_one_mac(&pConfig->routes[i][3],&routes[i].out_mac[0]);
+ memcpy(&routes[i].out_mac[6], ((port==1) ?&config.mac0[0]: &config.mac1[0] ),6);
+ routes[i].out_mac[12]=0x08;
+ routes[i].out_mac[13]=0x00;
+ routes[i].sec_ptr=NULL;
+ n_routes+=1;
+ }
+ else if (strncmp(&pConfig->routes[i][0],"SA",2)==0)
+ {
+ said=atoi(&pConfig->routes[i][2]) ;
+ routes[i].sec_ptr=&sa_info[said];
+ n_routes+=1;
+ }
+ }
+}
+our_router = route_init();
+for (i=0;i<MAX_ROUTES;i++)
+{
+ unsigned long ip_be;
+ int route_index;
+ if (pConfig->dst_ips[i][0])
+ {
+ parse_one_ip(&pConfig->dst_ips[i][0],(unsigned char *)&ip_be);
+ sscanf(&pConfig->paths[i][0],"route%d",&route_index);
+ route_add(our_router,&ip_be,&routes[route_index]);
+ n_dst_ips+=1;
+ }
+}
+printf(">Route DB built. %d entries\n",n_dst_ips);
+}
+#endif
+static void parse_config_file(FILE * fpr, netTestConfigFile_t *pConfig)
+{
+ char line[MAX_LINE_LENGTH + 1];
+ int i;
+
+ char *key, *data, *ep, *data2;
+ char tokens[] = " :=;\n";
+ char temp_str[50];
+ memset(line, 0, MAX_LINE_LENGTH + 1);
+ memset(pConfig, 0, sizeof(netTestConfigFile_t));
+ while (fgets(line, MAX_LINE_LENGTH + 1, fpr))
+ {
+ if(line[0]=='#') continue; //skip comment
+ key = (char *)strtok(line, tokens);
+ data = (char *)strtok(NULL, tokens);
+ data2 = (char *)strtok(NULL, tokens);
+ if (!key) continue;
+ if (!data) continue;
+
+ if(strlen(data) == 0)
+ {
+ continue;
+ }
+
+ CHECK_SET_PARAM(INIT_CONFIG_MAC0,&(pConfig->mac0[0]));
+ CHECK_SET_PARAM(INIT_CONFIG_MAC1,&(pConfig->mac1[0]));
+ CHECK_SET_PARAM(INIT_CONFIG_IP0,&(pConfig->ip0[0]));
+ CHECK_SET_PARAM(INIT_CONFIG_IP1,&(pConfig->ip1[0]));
+ CHECK_SET_PARAM(INIT_CONFIG_IP2,&(pConfig->ip2[0]));
+ CHECK_SET_PARAM(INIT_CONFIG_LOCAL_IPSEC_IP,&(pConfig->local_ipsec_ip[0]));
+ CHECK_SET_PARAM(INIT_CONFIG_REMOTE_IPSEC_IP,&(pConfig->remote_ipsec_ip[0]));
+ CHECK_SET_PARAM(INIT_CONFIG_IPSEC_MODE_RX,&(pConfig->ipsec_mode_rx[0]));
+ CHECK_SET_PARAM(INIT_CONFIG_IPSEC_MODE_TX,&(pConfig->ipsec_mode_tx[0]));
+ CHECK_SET_PARAM(INIT_CONFIG_IPSEC_IF_NO,&(pConfig->ipsec_if_no[0]));
+#ifdef EXPERIMENTAL
+ for(i=0;i<MAX_ROUTES;i++)
+ {
+ sprintf(temp_str,"route%d",i);
+ CHECK_SET_PARAM2(temp_str,&pConfig->routes[i][0],&pConfig->ports[i][0] );
+ }
+ for(i=0;i<MAX_ROUTES;i++)
+ {
+ sprintf(temp_str,"dstip%d",i);
+ CHECK_SET_PARAM2(temp_str,&pConfig->dst_ips[i][0],&pConfig->paths[i][0] );
+ }
+#endif
+
+ }
+ parse_mac_address(pConfig);
+
+ parse_ip_address(pConfig);
+
+ parse_ipsec_mode(pConfig);
+#ifdef EXPERIMENTAL
+ if (strlen(&pConfig->ipsec_if_no[0]))
+ config.ipsec_if_no = atoi(&pConfig->ipsec_if_no[0]);
+ parse_routes(pConfig);
+#endif
+}
+static netTestConfigFile_t config_file;
/***************************************
********** test driver*****************
***************************************/
int main(int argc, char **argv)
{
-int err;
-rlim_t oss,ss = 1024*1024;
-struct rlimit rl;
-
-Pktlib_HeapCfg heapCfg;
-int32_t errCode;
-Pktlib_HeapIfTable* pPktifTable;
+ int err,i;
+ rlim_t oss,ss = 1024*1024;
+ struct rlimit rl;
+
+ Pktlib_HeapCfg heapCfg;
+ int32_t errCode;
+ Pktlib_HeapIfTable* pPktifTable;
+
+ FILE * fpr = NULL;
-err= getrlimit(RLIMIT_STACK,&rl);
-if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");
+
+
+ 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");
+ rl.rlim_cur = ss;
+ err=setrlimit(RLIMIT_STACK,&rl);
+i f (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");
+#endif
+
+
+ if (argc>=2) np2process = atoi(argv[1]);
+ printf("*************** np2process %d\n", np2process);
+ if (np2process<0) np2process = NP; /* default */
+ if (argc==3) perslow = atoi(argv[2]);
+ if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default
+ if (argc>3) {printf("net_test <no of pkts to process> <percent slow path>\n"); exit(1);}
+#if 1
+
+#if 0
+ if (argc >= 2)
+ {
+ fpr = fopen(argv[2], "r");
+ if (fpr == NULL)
+ {
+ printf("Error in opening %s input file\n", argv[2]);
+ }
+ }
+ else
+#endif
+ {
+ fpr = fopen(input_file_name, "r");
+ if (fpr == NULL)
+ {
+ printf("Error in opening %s input file\n", input_file_name);
+ }
+ else
+ {
+ parse_config_file(fpr,&config_file);
+ }
+ }
+
#endif
-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 <no of pkts to process> <percent slow path>\n"); exit(1);}
+ memset(&sa_info, 0, sizeof(sa_info));
//real mode, so update our test packet mac header and ip header
memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address
memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses
}
+#if 0
+our_router = route_init();
+for (i=0;i<n_dst_ips;i++)
+{
+ route_add(our_router,&ip[i],&routes[i]);
+}
+#endif
/*******************************************/
/*************NETAPI STARTUP****************/
exit(1);
#endif
+#ifndef EXPERIMENTAL
/* create a pktio channel */
our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb_bench, &our_chan_cfg,&err);
if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}
+#endif
/* open netcp default tx, rx queues */
netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err);
if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}
+#ifdef EXPERIMENTAL
+netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg, &err);
+#else
netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg, &err);
+#endif
if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
+#ifndef EXPERIMENTAL
/* create a pktio channel for specially classified pkts */
netcp_rx_chan2= pktio_create(netapi_handle, "classq", (PKTIO_CB) recv_cb, &netcp_rx_cfg2, &err);
if (!netcp_rx_chan2) {printf("pktio create RX2 failed err=%d\n",err); exit(1);}
@@ -1562,6 +2480,7 @@ netcp_sb_tx_chan= pktio_open(netapi_handle, NETCP_SB_TX, NULL, &netcp_sb_tx_cfg,
if (!netcp_sb_tx_chan) {printf("pktio open SB TX failed err=%d\n",err); exit(1);}
netcp_sb_rx_chan= pktio_open(netapi_handle, NETCP_SB_RX, (PKTIO_CB) recv_sb_cb, &netcp_sb_rx_cfg, &err);
if (!netcp_sb_rx_chan) {printf("pktio open SB RX failed err=%d\n",err); exit(1);}
+#endif
printf("net_test> %d bytes left in our CMA area\n", netapi_getBufMemRemainder());
/* create scheduler instance */
/* add mac intefaces */
netcp_cfgCreateMacInterface(
netapi_handle,
- &mac0[0],
+ &config.mac0[0],
0,0,
(NETCP_CFG_ROUTE_HANDLE_T) NULL,
(NETCP_CFG_VLAN_T ) NULL , //future
netapi_handle,
0,
nwal_IPV4,
- &OurIp0,
+ &config.ip0,
NULL, //all IP
(NETCP_CFG_ROUTE_HANDLE_T) NULL,
&err
//create a 2nd mac instance
netcp_cfgCreateMacInterface(
netapi_handle,
- &mac1[0],
+ &config.mac1[0],
1,1,
(NETCP_CFG_ROUTE_HANDLE_T) NULL,
(NETCP_CFG_VLAN_T ) NULL , //future
netapi_handle,
1,
nwal_IPV4,
- &OurIp1,
+ &config.ip1,
NULL, //all IP
(NETCP_CFG_ROUTE_HANDLE_T) NULL,
&err
);
if (err) {printf("addip1 failed %d\n",err); exit(1); }
+#ifndef EXPERIMENTAL
//attach 2 classifiers to iface 0, ip0
class_0_cfg.u.c_l4.ip = ip_rule0;
class_0 = netcp_cfgAddClass(netapi_handle,
//3rd classifier has a different IP and route
-class_2_cfg.u.c_l3_l4.ip_addr = &OurIp2;
+class_2_cfg.u.c_l3_l4.ip_addr = &config.ip2;
//create specialFlow for this classifier
{
#define SPECIAL_SOP_OFF 128
sizes[0]=512-SPECIAL_SOP_OFF;
sizes[1]=1600-SPECIAL_SOP_OFF;
+#if 0
specialFlow = netcp_cfgAddFlow( netapi_handle,
2,
heaps,
SPECIAL_SOP_OFF, //offset to start rx is 128
&err);
if (err) {printf("add flow failed\n", err); exit(1);}
+#endif
}
#if 0
//special route for this classifier: different flow + destination q
if (err) {printf("addclass2 failed %d\n",err); exit(1);}
#endif
+#endif
//security stuff
-ourRXKeyParams.pEncKey = &ourEncrKey[0];
-ourRXKeyParams.pAuthKey = &ourAuthKey[0];
-memcpy(&rx_sa.src, &TheirIp4IPSEC,4);
-memcpy(&rx_sa.dst, &OurIp4IPSEC,4);
+ p_trie_sa = trie_new();
+ if (!p_trie_sa) {printf("trie alloc for SA failed\n"); exit(1);}
-#if 1
-rx_tunnel = netapi_secAddSA( netapi_handle,
- 0, //iface #0
- &rx_sa,
- &ourRXKeyParams,
-#ifdef IPSEC_MODE_RX_SIDEBAND
- NETAPI_SEC_SA_SIDEBAND,
-#else
- NETAPI_SEC_SA_INFLOW, //USE inflow mode
-#endif
+
+
+ for (i=0; i < MAX_SEC_INDEX;i++)
+ {
+ ourRXKeyParams[i].pEncKey = &ourEncrKey[0];
+ ourRXKeyParams[i].pAuthKey = &ourAuthKey[0];
+ memcpy(&(rx_sa[i].src), &config.remote_ipsec_ip,4);
+ memcpy(&(rx_sa[i].dst), &config.local_ipsec_ip,4);
+
+ build_sa_db(i);
+ sa_info[i].rx_tunnel = netapi_secAddSA(
+ netapi_handle,
+ config.ipsec_if_no, //iface #0
+ &rx_sa[i],
+ &ourRXKeyParams[i],
+ config.ipsec_mode_rx == IPSEC_MODE_RX_SIDEBAND ? NETAPI_SEC_SA_SIDEBAND: NETAPI_SEC_SA_INFLOW,
NULL, //use default route
- &rx_data_mode_handle,
- &rx_inflow_mode_handle,
- &err);
-if (err) {printf("addRxSa failed %d\n",err); exit(1);}
-
-#ifdef IPSEC_MODE_RX_INFLOW
-//assume inner and outer ip is the same
-rx_policy= netapi_secAddRxPolicy( netapi_handle,
- rx_tunnel, //link to tunnel above
+ &(sa_info[i].rx_data_mode_handle),
+ &(sa_info[i].rx_inflow_mode_handle),
+ &err);
+ if (err) {printf("addRxSa failed %d\n",err); exit(1);}
+
+ if (config.ipsec_mode_rx == IPSEC_MODE_RX_INFLOW)
+ {
+ //assume inner and outer ip is the same
+ rx_policy[i]= netapi_secAddRxPolicy( netapi_handle,
+ sa_info[i].rx_tunnel, //link to tunnel above
4, //ipv4
- &TheirIp4IPSEC, //src -> them
- &OurIp4IPSEC, //dst -> us
- NULL, // no qualifiers
- NULL, //default route
+ &config.remote_ipsec_ip, //src -> them
+ &config.local_ipsec_ip, //dst -> us
+ NULL, // no qualifiers
+ NULL, //default route
&err);
-if (err) {printf("addSaPolicy failed %d\n",err); exit(1);}
-#else
-rx_policy = 0;
-#endif
-#endif
+ if (err) {printf("addSaPolicy failed %d, for index %d\n",err,i); exit(1);}
+ }
+ else
+ rx_policy[i] = 0;
+ }
//tx SA
//security stuff
-ourTXKeyParams.pEncKey = &ourEncrKey[0];
-ourTXKeyParams.pAuthKey = &ourAuthKey[0];
-memcpy(&tx_sa.src, &OurIp4IPSEC,4);
-memcpy(&tx_sa.dst, &TheirIp4IPSEC,4);
-tx_tunnel = netapi_secAddSA( netapi_handle,
+ for (i=0; i < MAX_SEC_INDEX;i++)
+ {
+ ourTXKeyParams[i].pEncKey = &ourEncrKey[0];
+ ourTXKeyParams[i].pAuthKey = &ourAuthKey[0];
+ memcpy(&(tx_sa[i].src), &config.local_ipsec_ip,4);
+ memcpy(&(tx_sa[i].dst), &config.remote_ipsec_ip,4);
+ sa_info[i].tx_tunnel = netapi_secAddSA( netapi_handle,
0, //iface #0
- &tx_sa,
- &ourTXKeyParams,
-#ifdef IPSEC_MODE_TX_SIDEBAND
- NETAPI_SEC_SA_SIDEBAND,
-#else
- NETAPI_SEC_SA_INFLOW, //USE inflow mode
-#endif
+ &(tx_sa[i]),
+ &ourTXKeyParams[i],
+ config.ipsec_mode_tx == IPSEC_MODE_TX_SIDEBAND ? NETAPI_SEC_SA_SIDEBAND: NETAPI_SEC_SA_INFLOW,
NULL, //use default route
- &tx_data_mode_handle,
- &tx_inflow_mode_handle,
+ &(sa_info[i].tx_data_mode_handle),
+ &(sa_info[i].tx_inflow_mode_handle),
&err);
if (err) {printf("addTxSa failed %d\n",err); exit(1);}
-
+ }
#ifdef TEST_TIMERS
//timers
ourTimerBlock = netapi_TimerGroupCreate(
#endif
/**************unused stuff******************/
+#if 0
/* create TRIE */
P_trie = trie_new();
if (!P_trie) {printf("trie alloc failed\n"); exit(1);}
/* processing loop: get pkt, check it, look up in table, copy new header,
send packet */
srand((unsigned) np2process);
-
+#endif
/*********************************************/
/**************Entry point into scheduler ****/
#define DO_FAST_POLL
#ifdef DO_FAST_POLL
-example_fast_pushpop(OurHeap, 500);
-example_fast_poll(netcp_rx_chan,100000);
+//example_fast_pushpop(OurHeap, 500);
+//example_fast_poll(netcp_rx_chan,20000);
#endif
/*************************************************
************CLEAN UP****************************
************************************************/
+#ifndef EXPERIMENTAL
//delete Classifiers
netcp_cfgDelClass(netapi_handle, class_0, &err);
netcp_cfgDelClass(netapi_handle, class_1, &err);
//netcp_cfgDelClass(netapi_handle, class_2, &err);
+#if 0
//delete flow
netcp_cfgDelFlow(netapi_handle, specialFlow, &err);
-
+#endif
+#endif
#if 1
//delete policy
-if (rx_policy)
- netapi_secDelRxPolicy(netapi_handle, rx_policy, &err);
-
-//delete tunnels
-netapi_secDelSA(netapi_handle, 0, rx_tunnel, &err);
-netapi_secDelSA(netapi_handle, 0, tx_tunnel, &err);
+ for (i=0; i < MAX_SEC_INDEX;i++)
+ {
+ if (rx_policy[i])
+ netapi_secDelRxPolicy(netapi_handle, rx_policy[i], &err);
+
+ //delete tunnels
+ netapi_secDelSA(netapi_handle, 0, sa_info[i].rx_tunnel, &err);
+ netapi_secDelSA(netapi_handle, 0, sa_info[i].tx_tunnel, &err);
#endif
-
+ }
//delete IPs and MAC Interfacess
netcp_cfgDelIp(netapi_handle, 0, 0, NULL, NULL, ip_rule0, &err);
netcp_cfgDelIp(netapi_handle, 1, 0, NULL, NULL, ip_rule1, &err);
//close pktio channels we opened
pktio_close(netcp_tx_chan ,&err);
pktio_close(netcp_rx_chan ,&err);
+#ifndef EXPERIMENTAL
pktio_close(netcp_sb_tx_chan ,&err);
pktio_close(netcp_sb_rx_chan ,&err);
@@ -1867,7 +2800,7 @@ pktio_control(netcp_rx_chan2, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channe
//delete pktio channels we created
pktio_delete(our_chan, &err);
pktio_delete(netcp_rx_chan2,&err);
-
+#endif
netapi_shutdown(netapi_handle);
}
}
}
-
+ //cleanup any remaining buffers
+ for(;;)
+ {
+ pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
+ if(!pHd[0]) break;
+ tempVA = Osal_qmssPhyToVirt(pHd[0]);
+ freeQ=Qmss_getQueueHandle(Cppi_getReturnQueue (Cppi_DescType_HOST, (Cppi_Desc *)tempVA));
+ netapi_utilCacheWbInv(tempVA,128);
+ PKTIO_QMSS_QUEUE_PUSH_DESC_SIZE_RAW (freeQ,
+ (void *) pHd[0],
+ 128);
+ }
}
+#ifdef EXPERIMENTAL
+static inline void send_it(Ti_Pkt *tip, int len, ROUTE_SEC_T * p_sec)
+{
+ unsigned long st1;
+ unsigned long st2;
+ int err=0;
+ PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
+ nwalTxPktInfo_t meta_tx2={0};
+ st1=netapi_timing_start();
+ if (len<60)
+ {
+ unsigned int templen;
+ char * p_pkt;
+ len=60;
+ Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
+ Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
+ stats.tx_min+=1;
+ }
+ Pktlib_setPacketLen(tip,len);
+ meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
+ meta_tx2.startOffset = 0;
+ meta_tx2.ipOffBytes = 14;
+ meta_tx2.ploadLen = len ;
+ if(p_sec)
+ {
+ meta_tx2.txFlag1 |= NWAL_TX_FLAG1_DO_IPSEC_CRYPTO ;
+ meta2.sa_handle=p_sec->tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied
+ meta_tx2.enetPort=0;
+ meta_tx2.saOffBytes=14+20;
+ meta_tx2.saPayloadLen=len-14-20; //don't include tag, mac and outer header
+ stats.sec_tx+=1;
+ }
+ meta2.u.tx_meta=&meta_tx2;
+ pktio_send(netcp_tx_chan,tip,&meta2,&err);
+ stats.tx +=1;
+ st2=netapi_timing_start();
+ stats.send_cycles += (unsigned long long) (st2-st1);
+}
+void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
+ PKTIO_METADATA_T meta[], int n_pkts,
+ uint64_t ts )
+{
+int i;
+int len;
+int p;
+Ti_Pkt * tip;
+unsigned int templen;
+char * p_pkt;
+HEAD_T temp_head;
+unsigned int appid;
+IP_HEAD_T th;
+ROUTE_SEC_T *sec_data=NULL;
+unsigned long t1;
+unsigned long t2;
+unsigned long ct1;
+unsigned long ct2;
+unsigned short ip_pl;
+int n_c_ops;
+t1=netapi_timing_start();
+ct1 =Osal_cache_op_measure(&n_c_ops);
+for(i=0;i<n_pkts;i++)
+{
+ tip = p_recv[i];
+ Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
+ len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
+ stats.rx+=1;
+ appid = ((unsigned int)meta[i].u.rx_meta->appId)&0xff000000;
+ switch(appid)
+ {
+ case(NETAPI_NETCP_MATCH_IPSEC):
+ case(NETAPI_NETCP_MATCH_IPSEC_POLICY):
+ {
+ int tailen=12+2;
+ memcpy(&temp_head,&p_pkt[14],sizeof(HEAD_T));
+ if (!check_header(&temp_head,&meta[i])) {
+ stats.n_bad+=1;
+ Pktlib_freePacket(tip);
+ continue;
+ }
+ tailen+=p_pkt[len-12-2]; //padding length (12)should come from sec_ptr
+ p_pkt = &p_pkt[8+16+20]; //16= iv len, should come from sec_ptr
+ len -= (8+16+20+tailen); //16= iv len should come from sec ptr
+
+ //now check inner headder.
+ memcpy(&th,&p_pkt[14],20);
+ if (!check_header(&temp_head,&meta[i])) {
+ stats.n_bad+=1;
+ Pktlib_freePacket(tip);
+ continue;
+ }
+ Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
+ Pktlib_setPacketLen(tip,len);
+
+ if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data)<0)
+ {
+ stats.n_bad+=1;
+ Pktlib_freePacket(tip);
+ }
+ else
+ {
+ send_it(tip,len,sec_data);
+ }
+ break;
+ }
+ case(NETAPI_NETCP_MATCH_GENERIC_MAC):
+ if((p_pkt[12]!=0x8)||(p_pkt[13]!=0x00))
+ {
+ stats.n_new+=1;
+ Pktlib_freePacket(tip);
+ continue;
+ }
+ if (!check_header(&temp_head,&meta[i]))
+ {
+ stats.n_bad+=1;
+ Pktlib_freePacket(tip);
+ continue;
+ }
+ memcpy(&th,&p_pkt[14],20);
+ ip_pl= (((unsigned char *)&th.w1)[2]<<8) | ((unsigned char *)&th.w1)[3];
+ if ((ip_pl+14)<60)
+ {
+ len-= (60-(ip_pl+14));
+ stats.rx_min+=1;
+ }
+ Pktlib_setPacketLen(tip,len);
+ if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data)<0)
+ {
+ stats.n_bad+=1;
+ Pktlib_freePacket(tip);
+ }
+ else
+ {
+ send_it(tip,len,sec_data);
+ }
+ break;
+ case(NETAPI_NETCP_MATCH_GENERIC_IP):
+ Pktlib_freePacket(tip);
+ stats.n_new=1;
+ break;
+ default:
+ stats.n_new+=1;
+ Pktlib_freePacket(tip);
+ break;
+ }
+}
+t2=netapi_timing_start();
+ct2 =Osal_cache_op_measure(&n_c_ops);
+stats.app_cycles += (unsigned long long) (t2-t1);
+stats.tx_cache_cycles += (unsigned long long) (ct2-ct1);
+return;
+}
+#endif
diff --git a/ti/runtime/netapi/test/net_test.h b/ti/runtime/netapi/test/net_test.h
--- /dev/null
@@ -0,0 +1,186 @@
+/******************************************************************************
+ * FILE PURPOSE: local defines for net_test application.
+ ******************************************************************************
+ * FILE NAME: net_test.h
+ *
+ * DESCRIPTION: NET TEST definitions and defines
+ *
+ * REVISION HISTORY:
+ *
+ * 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.
+ *
+ */
+/* ============================================================= */
+
+//IPSEC MODE(only choose one rx and one tx)
+
+#define IPSEC_MODE_RX_INFLOW 1
+#define IPSEC_MODE_TX_INFLOW 2
+#define IPSEC_MODE_RX_SIDEBAND 3
+#define IPSEC_MODE_TX_SIDEBAND 4
+
+#define MAX_SEC_INDEX 4
+#define netTest_MAC_HEADER_LEN 14
+#define netTest_IP_HEADER_LEN 20
+#define netTest_UDP_HEADER_LEN 8
+#define netTest_ESP_HEADER_LEN 8
+#define netTest_AES_CBC_IV_LEN 16
+#define netTest_AES_CTR_IV_CONTEXT_LEN 16
+#define netTest_AES_CTR_IV_PACKET_LEN 8
+#define netTest_3DES_CBC_IV_LEN 8
+#define netTest_NULL_IV_LEN 0
+#define netTest_ICV_LEN 12
+
+
+
+/* The input strings for the input config file is given below */
+#define INIT_CONFIG_MAC0 "mac0"
+#define INIT_CONFIG_MAC1 "mac1"
+#define INIT_CONFIG_IP0 "ip0"
+#define INIT_CONFIG_IP1 "ip1"
+#define INIT_CONFIG_IP2 "ip2"
+#define INIT_CONFIG_LOCAL_IPSEC_IP "local_ipsec_ip"
+#define INIT_CONFIG_REMOTE_IPSEC_IP "remote_ipsec_ip"
+#define INIT_CONFIG_IPSEC_MODE_RX "ipsec_mode_rx"
+#define INIT_CONFIG_IPSEC_MODE_TX "ipsec_mode_tx"
+#define INIT_CONFIG_IPSEC_IF_NO "ipsec_if"
+
+
+#define CONFIG_STRING_LEN 25
+
+
+
+
+#define MAX_ROUTES 16
+/* tmannan - begin */
+
+typedef struct {
+ nwalDmTxPayloadInfo_t tx_payload_info;
+ uint8_t inner_ip_offset;
+ NETCP_CFG_SA_T rx_tunnel;
+ void * rx_data_mode_handle;
+ void * rx_inflow_mode_handle;
+ NETCP_CFG_SA_T tx_tunnel;
+ void * tx_data_mode_handle;
+ void * tx_inflow_mode_handle;
+ uint8_t enc_key_length;
+ uint8_t auth_tag_size;
+ nwalTxPktInfo_t tx_pkt_info;
+ nwal_saEALG cipherMode;
+ /*stuff for routing use case */
+ unsigned int src; //BE
+ unsigned int dst; //BE
+ unsigned int spi; //BE
+ unsigned int seq; //BE
+ int iv_len; //iv len (size of iv in pkt)
+ int bl; //block len (for padding calc)
+} netTestSA_t;
+
+
+
+typedef struct{
+ char mac0[CONFIG_STRING_LEN];
+ char mac1[CONFIG_STRING_LEN];
+ char ip0[CONFIG_STRING_LEN];
+ char ip1[CONFIG_STRING_LEN];
+ char ip2[CONFIG_STRING_LEN];
+ char local_ipsec_ip[CONFIG_STRING_LEN];
+ char remote_ipsec_ip[CONFIG_STRING_LEN];
+ char ipsec_mode_rx[CONFIG_STRING_LEN];
+ char ipsec_mode_tx[CONFIG_STRING_LEN];
+ char routes[MAX_ROUTES][CONFIG_STRING_LEN];
+ char ports[MAX_ROUTES][CONFIG_STRING_LEN];
+ char dst_ips[MAX_ROUTES][CONFIG_STRING_LEN];
+ char paths[MAX_ROUTES][CONFIG_STRING_LEN];
+ char ipsec_if_no[CONFIG_STRING_LEN];
+} netTestConfigFile_t;
+
+
+
+
+typedef struct {
+unsigned char mac0[6];
+unsigned char mac1[6];
+nwalIpAddr_t ip0;
+nwalIpAddr_t ip1;
+nwalIpAddr_t ip2;
+nwalIpAddr_t local_ipsec_ip;
+nwalIpAddr_t remote_ipsec_ip;
+uint8_t ipsec_mode_rx;
+uint8_t ipsec_mode_tx;
+int ipsec_if_no; /* 0 if mac0, 1 if mac 1 */
+
+} netTestConfig_t;
+
+typedef struct stats_t
+{
+ long itx; //initially generated
+ long itx2;
+ long rx;
+ long tx;
+ long n_bad;
+ long n_new;
+ long n_class0_rx; //count of pkts classified
+ long n_class1_rx; //count of pkts classified
+ long n_class2_rx; //count of pkts classified
+ long n_t1;
+ long n_t2;
+ long n_t3;
+ long sec_tx;
+ long sec_rx;
+ long sb_tx;
+ long sb_rx;
+ long secp_rx;
+ long n_auth_ok;
+ unsigned long long app_cycles;
+ unsigned long long send_cycles;
+ unsigned long long tx_cache_cycles;
+ unsigned long long total_decrypt_time;
+ unsigned long long total_encrypt_time;
+ long rx_min;
+ long tx_min;
+} 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;
+
+
diff --git a/ti/runtime/netapi/test/net_test_config.txt b/ti/runtime/netapi/test/net_test_config.txt
--- /dev/null
@@ -0,0 +1,19 @@
+mac0 = 00-01-02-03-05-05
+mac1 = 00-01-02-03-05-06
+ip0 = 10.0.0.100
+ip1 = 10.0.1.100
+ip2 = 10.0.2.100
+local_ipsec_ip = 192.168.1.100
+remote_ipsec_ip = 192.168.1.10
+ipsec_if = 0
+#ipsec_mode_rx = SIDEBAND
+#ipsec_mode_rx = SIDEBAND
+ipsec_mode_rx = INFLOW
+ipsec_mode_tx = INFLOW
+
+
+route0 = MAC00-23-24-08-67-46 1
+route1 = MAC00-22-33-44-55-56 2
+
+dstip0 = 10.1.0.100 route1
+dspip1 = 10.0.0.10 route0
diff --git a/ti/runtime/netapi/test/router.c b/ti/runtime/netapi/test/router.c
--- /dev/null
@@ -0,0 +1,169 @@
+#include "trie.h"
+
+#define BE(x) ( (((x)&0xff000000)>>24) | (((x)&0xff0000)>>8) | (((x)&0xff00)<<8) | (((x)&0xff)<<24) )
+
+typedef struct iphead_t
+{
+ unsigned long w1;
+ unsigned long w2;
+ unsigned long w3;
+ unsigned long src;
+ unsigned long dst;
+} IP_HEAD_T;
+
+#define ROUTE_SEC_T netTestSA_t
+
+typedef struct our_route_t
+{
+ int out_port;
+ unsigned char out_mac[14];
+ ROUTE_SEC_T * sec_ptr;
+} OUR_ROUTE_T;
+
+
+
+Trie * route_init(void)
+
+{
+
+Trie *Pt = trie_new();
+
+return Pt;
+
+}
+
+
+
+void route_add(Trie * Pt, unsigned int * Pdest_ipBE, void * Pour_route)
+{
+
+ trie_insert(Pt,(char *)Pdest_ipBE, sizeof(int), Pour_route);
+}
+
+//route the packet
+// lookup next hop in route trie
+int route_pkt(Trie *Pt, void * Ppkt, IP_HEAD_T *Phead, unsigned char * Pbuf, int * Plen, ROUTE_SEC_T **Prs)
+{
+ OUR_ROUTE_T *Pr;
+ int ret;
+ Pr = trie_lookup(Pt, (char *) &Phead->dst, 4);
+ if (!Pr ) return -1; //can't route
+ if (Pr->sec_ptr)
+ {
+ if(!Prs) return -3;
+ //tunnel i/f
+ ret=process_tunnel(Pt, Ppkt, Phead, Pbuf, Plen, Pr);
+ *Prs = Pr->sec_ptr;
+ return ret;
+ }
+ if (Prs) *Prs=NULL;
+ //simple route
+ //copy new mac
+ memcpy(Pbuf,Pr->out_mac,14);
+ Pbuf[14+8]-=1; //ttl--
+ //todo do check ttl!
+ Pbuf[14+10]=0; Pbuf[14+11]=0; //zap [outer] header checksum
+ return 1;
+}
+
+int process_tunnel(Trie *Pt, void *Ppkt, IP_HEAD_T * Phead,
+ unsigned char * Pbuf, int* Plen, OUR_ROUTE_T * Proute)
+{
+unsigned char *sb = Pbuf;
+unsigned char *eb= &Pbuf[*Plen];
+int newlen=*Plen;
+int seq;
+int pl_len;
+int new_pl_len;
+int pad_len;
+//unsigned char IV[20];
+ROUTE_SEC_T * p_sec=Proute->sec_ptr;
+unsigned char *pc;
+int nb;
+int i;
+int ret;
+
+/* move sb to new start */
+sb = sb - p_sec->iv_len-8-20; //make room for esp header and new outer ip
+newlen += (Pbuf-sb);
+
+//adjust IP_Header to make outer:
+Phead->src=p_sec->src;
+Phead->dst=p_sec->dst;
+
+//next_proto
+pc = (unsigned char *)&Phead->w3;
+pc[1]=50;
+
+//payload len
+pc= (unsigned char*)&Phead->w1;
+pl_len= ((pc[2]<<8) | (pc[3]));
+
+//pad length
+nb = pl_len/p_sec->bl; //128 for AES
+pad_len = pl_len - nb*p_sec->bl;
+switch(pad_len)
+{
+ case(15):
+ pad_len=15;
+ break;
+ default:
+ pad_len = p_sec->bl-pad_len-2;
+}
+
+new_pl_len = pl_len + +20+ 8 + p_sec->iv_len + pad_len + p_sec->auth_tag_size +2;
+pc[2] = (new_pl_len&0xff00)>>8;
+pc[3] = (new_pl_len&0xff);
+memcpy(&sb[14],Phead,20); //copy outer ip header into buffer
+
+//build esp header
+memcpy(&sb[14+20],(unsigned char *)&p_sec->spi,4);
+seq=BE(p_sec->seq++); //TODO: multicore safe ; CHECK to make sure that SA does this, if so remove this code
+memcpy(&sb[14+24],(unsigned char *)&seq,4);
+
+//IV: don't need: Sa does it.
+//memcpy(&sb[14+28],&IV[0],p_sec->iv_len);
+
+//Padding, trailer, room for tag
+for(i=1;i<=pad_len;i++) *eb++ = i;
+*eb++=pad_len; //pad len
+*eb++=4; //next proto= ipinip
+newlen += pad_len+2+p_sec->auth_tag_size;
+Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) Ppkt, sb,newlen);
+Pktlib_setPacketLen(Ppkt,newlen);
+
+//now route based on outer ip
+ret=route_pkt(Pt, Ppkt, Phead, sb, &newlen,NULL);
+if (ret<0) return ret;
+*Plen=newlen;
+return 1;
+}
+//#define TEST
+#ifdef TEST
+#define NR 4
+OUR_ROUTE_T routes[]=
+{
+{1,{0x00,0x01,0x2,0x03,0x4,0x2, 0x00,0x01,0x02,0x03,0x14,0x02,0x00,0x80},0},
+{2,{0x00,0x01,0x2,0x03,0x4,0x3, 0x00,0x01,0x02,0x03,0x24,0x02,0x00,0x80},0},
+{3,{0x00,0x01,0x2,0x03,0x4,0x4, 0x00,0x01,0x02,0x03,0x34,0x02,0x00,0x80},0},
+{4,{0x00,0x01,0x2,0x03,0x4,0x5, 0x00,0x01,0x02,0x03,0x44,0x02,0x00,0x80},0}};
+
+unsigned int ip[]={BE(0x0a000010),BE(0xa0000110),BE(0x0a000210),BE(0x0a000310)};
+Trie *rt;
+char tp[1500];
+IP_HEAD_T th={0x00,0x00,0x00,0x01020304,0x1002000a};
+main()
+{
+int i;
+int l;
+rt = route_init();
+for (i=0;i<NR;i++)
+{
+ route_add(rt,&ip[i],&routes[i]);
+}
+
+memcpy(&tp[14],&th,20);
+l=1500;
+route_pkt(rt, 0, &th, &tp[0],&l,NULL);
+}
+#endif
index 639954c2c4e8efe152213ba82da50241747c5146..b8ce04b688e9441684e0572bc96cce069e3a2b3c 100755 (executable)
-/* stubs .. */\r
-/* place holder...*/\r
+/* stubs .. */
+/* place holder...*/
index 1a1f5c7913dbaec756a74fa3fb5af359bbd6654a..d5de741960fa97c13bf53f8feda00fc7307f625f 100755 (executable)
-/********************************\r
- * file: synchtest.c\r
- * sync primitives unit test\r
- ************************************************\r
-* FILE: synchtest.c \r
- * \r
- * DESCRIPTION: netapi user space transport\r
- * library test application -> synchronization primitives\r
- * \r
- * REVISION HISTORY: rev 0.0.1 \r
- *\r
- * Copyright (c) Texas Instruments Incorporated 2010-2011\r
- * \r
- * Redistribution and use in source and binary forms, with or without \r
- * modification, are permitted provided that the following conditions \r
- * are met:\r
- *\r
- * Redistributions of source code must retain the above copyright \r
- * notice, this list of conditions and the following disclaimer.\r
- *\r
- * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the \r
- * documentation and/or other materials provided with the \r
- * distribution.\r
- *\r
- * Neither the name of Texas Instruments Incorporated nor the names of\r
- * its contributors may be used to endorse or promote products derived\r
- * from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- ******************************/\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <unistd.h>\r
-#include <string.h>\r
-#include "netsync.h"\r
-#include "netapi_util.h"\r
-\r
-#if 0\r
-/* timing */\r
-static inline unsigned long timing_start(void)\r
-{\r
- volatile int vval;\r
- //read clock\r
- asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(vval));\r
- return vval;\r
-}\r
-static inline unsigned long timing_stop(void)\r
-{\r
- volatile int vval2;\r
- //read clock\r
- asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(vval2));\r
- return vval2;\r
-}\r
-#endif\r
-#define timing_start netapi_timing_start\r
-#define timing_stop netapi_timing_stop\r
-\r
-int spot=0;\r
-\r
-NETAPI_RWLOCK_T temp;\r
-\r
-void test1()\r
-{\r
-int v1, v2;\r
-netapi_rwlock_init(&temp);\r
-v1 = timing_start();\r
-netapi_rwlock_write_lock(&temp);\r
-v2 = timing_stop();\r
-printf("rwlock write locked, cycles= %d \n", v2-v1);\r
-}\r
-\r
-void test2()\r
-{\r
-int v1, v2;\r
-\r
-v1 = timing_start();\r
-netapi_rwlock_write_unlock(&temp);\r
-v2 = timing_stop();\r
-printf("rwlock write unlocked, cycles= %d \n",v2-v1);\r
-}\r
-void test3()\r
-{\r
-int v1,v2;\r
-v1 = timing_start();\r
-netapi_rwlock_read_lock(&temp);\r
-v2 = timing_stop();\r
-printf("rwlock read locked, cycles= %d \n", v2-v1);\r
-}\r
-void test4()\r
-{\r
-int v1,v2;\r
-v1 = timing_start();\r
-netapi_rwlock_read_unlock(&temp);\r
-v2 = timing_stop();\r
-printf("rwlock read_unlocked, cycles= %d\n", v2-v1);\r
-}\r
-\r
-main()\r
-{\r
-NETAPI_SPINLOCK_T val;\r
-int i;\r
-unsigned long v1,v2;\r
-int val2;\r
-for(i=0;i<10;i++) {\r
-val=__sync_fetch_and_add(&spot, 1);\r
-printf(" val = %d %d\n",val,spot);\r
-\r
-//now we try the synch_lock_and_test\r
-netapi_spinlock_init(&val);\r
-v1 = timing_start();\r
-netapi_spinlock_lock(&val);\r
-v2 = timing_stop();\r
-printf("locked, val= %d cycles=%d\n",val,v2-v1);\r
-\r
-//try the lock\r
-v1 = timing_start();\r
-val2=netapi_spinlock_try_lock(&val);\r
-v2 = timing_stop();\r
-printf("try lock has returns %d, cycles=%d\n", val2, v2-v1);\r
-\r
-//poll the lock \r
-v1 = timing_start();\r
-val2=netapi_spinlock_is_locked(&val);\r
-v2 = timing_stop();\r
-printf("is_locked has returns %d, cycles=%d\n", val2, v2-v1);\r
-\r
-\r
-//unlock\r
-v1 = timing_start();\r
-netapi_spinlock_unlock(&val);\r
-v2 = timing_stop();\r
-printf("unlocked, val= %d cycles=%d\n", val,v2-v1);\r
-\r
-/*-------now try rwlock--------*/\r
-test1();\r
-test2();\r
-test3();\r
-test3();\r
-test4();\r
-test4();\r
-\r
-}\r
-}\r
-\r
-\r
-\r
+/********************************
+ * file: synchtest.c
+ * sync primitives unit test
+ ************************************************
+* FILE: synchtest.c
+ *
+ * DESCRIPTION: netapi user space transport
+ * library test application -> synchronization primitives
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "netsync.h"
+#include "netapi_util.h"
+
+#if 0
+/* timing */
+static inline unsigned long timing_start(void)
+{
+ volatile int vval;
+ //read clock
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(vval));
+ return vval;
+}
+static inline unsigned long timing_stop(void)
+{
+ volatile int vval2;
+ //read clock
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(vval2));
+ return vval2;
+}
+#endif
+#define timing_start netapi_timing_start
+#define timing_stop netapi_timing_stop
+
+int spot=0;
+
+NETAPI_RWLOCK_T temp;
+
+void test1()
+{
+int v1, v2;
+netapi_rwlock_init(&temp);
+v1 = timing_start();
+netapi_rwlock_write_lock(&temp);
+v2 = timing_stop();
+printf("rwlock write locked, cycles= %d \n", v2-v1);
+}
+
+void test2()
+{
+int v1, v2;
+
+v1 = timing_start();
+netapi_rwlock_write_unlock(&temp);
+v2 = timing_stop();
+printf("rwlock write unlocked, cycles= %d \n",v2-v1);
+}
+void test3()
+{
+int v1,v2;
+v1 = timing_start();
+netapi_rwlock_read_lock(&temp);
+v2 = timing_stop();
+printf("rwlock read locked, cycles= %d \n", v2-v1);
+}
+void test4()
+{
+int v1,v2;
+v1 = timing_start();
+netapi_rwlock_read_unlock(&temp);
+v2 = timing_stop();
+printf("rwlock read_unlocked, cycles= %d\n", v2-v1);
+}
+
+main()
+{
+NETAPI_SPINLOCK_T val;
+int i;
+unsigned long v1,v2;
+int val2;
+for(i=0;i<10;i++) {
+val=__sync_fetch_and_add(&spot, 1);
+printf(" val = %d %d\n",val,spot);
+
+//now we try the synch_lock_and_test
+netapi_spinlock_init(&val);
+v1 = timing_start();
+netapi_spinlock_lock(&val);
+v2 = timing_stop();
+printf("locked, val= %d cycles=%d\n",val,v2-v1);
+
+//try the lock
+v1 = timing_start();
+val2=netapi_spinlock_try_lock(&val);
+v2 = timing_stop();
+printf("try lock has returns %d, cycles=%d\n", val2, v2-v1);
+
+//poll the lock
+v1 = timing_start();
+val2=netapi_spinlock_is_locked(&val);
+v2 = timing_stop();
+printf("is_locked has returns %d, cycles=%d\n", val2, v2-v1);
+
+
+//unlock
+v1 = timing_start();
+netapi_spinlock_unlock(&val);
+v2 = timing_stop();
+printf("unlocked, val= %d cycles=%d\n", val,v2-v1);
+
+/*-------now try rwlock--------*/
+test1();
+test2();
+test3();
+test3();
+test4();
+test4();
+
+}
+}
+
+
+
index b18f6db19a49e1e1b81ae970491b271ad5eb03b2..5a3717e1a3dae57263a0cbb01bfffb75170592de 100755 (executable)
-/**************************************\r
- * file : synchtest2.c\r
- **************************************\r
- * * FILE: synchtest2.c\r
- * \r
- * DESCRIPTION: netapi user space transport\r
- * library test application - more synchtest\r
- * \r
- * REVISION HISTORY: rev 0.0.1 \r
- *\r
- * Copyright (c) Texas Instruments Incorporated 2010-2011\r
- * \r
- * Redistribution and use in source and binary forms, with or without \r
- * modification, are permitted provided that the following conditions \r
- * are met:\r
- *\r
- * Redistributions of source code must retain the above copyright \r
- * notice, this list of conditions and the following disclaimer.\r
- *\r
- * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the \r
- * documentation and/or other materials provided with the \r
- * distribution.\r
- *\r
- * Neither the name of Texas Instruments Incorporated nor the names of\r
- * its contributors may be used to endorse or promote products derived\r
- * from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- ******************************************************************************/\r
-\r
-#include <stdio.h>\r
-#include <pthread.h>\r
-#include <unistd.h>\r
-#include <stdlib.h>\r
-#include <sched.h>\r
-#include <linux/unistd.h>\r
-#include <sys/syscall.h>\r
-#include <errno.h>\r
-\r
-#include "netsync.h"\r
-#include "netapi_util.h"\r
-//#define INC_TO 1000000 // one million.\r
-#define INC_TO 10000 // one million...\r
-\r
-NETAPI_ATOMIC64_T global_int=NETAPI_ATOMIC_INIT64(0LL) ;\r
-__thread blah=0;\r
-int blah2=0;\r
-NETAPI_SPINLOCK_T spin_test;\r
-\r
-pid_t gettid( void )\r
-{\r
- return syscall( __NR_gettid );\r
-}\r
-\r
-void *thread_routine( void *arg )\r
-{\r
- int i;\r
- int proc_num = (int)(long)arg;\r
- cpu_set_t set;\r
- int v1, v2,v3;\r
-\r
-#if 0\r
- CPU_ZERO( &set );\r
- CPU_SET( proc_num, &set );\r
-\r
- if (sched_setaffinity( gettid(), sizeof( cpu_set_t ), &set ))\r
- {\r
- perror( "sched_setaffinity" );\r
- return NULL;\r
- }\r
-#endif\r
-\r
- for (i = 0; i < INC_TO; i++)\r
- {\r
- \r
- v1 = netapi_timing_start(); \r
- netapi_atomic_add64(&global_int,1LL);\r
- v1= netapi_timing_stop() - v1;\r
- sched_yield();\r
- v2 = netapi_timing_start(); \r
- blah+=1; \r
- v2= netapi_timing_stop() - v2;\r
- \r
- v3 = netapi_timing_start(); \r
- blah2+=1; \r
- v3= netapi_timing_stop() - v3;\r
- if(i<10) { printf("thread %d -> a64 costs %d, tls costs %d simple++ costs %d\n", proc_num,v1,v2,v3);}\r
- sched_yield();\r
- }\r
- printf("thead %d -> blah=%d\n",proc_num, blah);\r
-\r
- printf("now try spin lock test. i'm thread %d, about to grab lock \n", proc_num);\r
-\r
- //now we try the synch_lock_and_test\r
- v1 = netapi_timing_start();\r
- netapi_spinlock_lock(&spin_test);\r
- v2 = netapi_timing_stop();\r
- printf("i'm thread %d. I've locked it, val= %d, it took cycles=%d to get it\ngoing to sleep..",proc_num,spin_test,v2-v1);\r
- sleep(1);\r
- printf(" i'm back. i'm thread %d. i'm unlocking now\n",proc_num); \r
- netapi_spinlock_unlock(&spin_test);\r
- return NULL;\r
-}\r
-\r
-int main()\r
-{\r
- int procs = 0;\r
- int i;\r
- pthread_t *thrs;\r
- printf("at start up\n");\r
-\r
- // Getting number of CPUs\r
- procs = (int)sysconf( _SC_NPROCESSORS_ONLN );\r
- if (procs < 0)\r
- {\r
- perror( "sysconf" );\r
- return -1;\r
- }\r
- printf(" num cpus = %d\n",procs);\r
- if (procs==1) {procs+=1; printf("adding 2nd 'core' \n");}\r
- thrs = malloc( sizeof( pthread_t ) * procs );\r
- if (thrs == NULL)\r
- {\r
- perror( "malloc" );\r
- return -1;\r
- }\r
-\r
- //initialize spinlock\r
- netapi_spinlock_init(&spin_test);\r
- printf( "Starting %d threads...\n", procs );\r
-\r
- for (i = 0; i < procs; i++)\r
- {\r
- if (pthread_create( &thrs[i], NULL, thread_routine,\r
- (void *)(long)i ))\r
- {\r
- perror( "pthread_create" );\r
- procs = i;\r
- break;\r
- }\r
- }\r
-\r
- for (i = 0; i < procs; i++)\r
- pthread_join( thrs[i], NULL );\r
-\r
- free( thrs );\r
-\r
- printf( "global_int value is: %lld bare global_int is %d\n",\r
- global_int.val, blah2 );\r
- printf( "Expected value is: %d\n", INC_TO * procs );\r
-\r
- return 0;\r
-}\r
+/**************************************
+ * file : synchtest2.c
+ **************************************
+ * * FILE: synchtest2.c
+ *
+ * DESCRIPTION: netapi user space transport
+ * library test application - more synchtest
+ *
+ * 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 <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <linux/unistd.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+#include "netsync.h"
+#include "netapi_util.h"
+//#define INC_TO 1000000 // one million.
+#define INC_TO 10000 // one million...
+
+NETAPI_ATOMIC64_T global_int=NETAPI_ATOMIC_INIT64(0LL) ;
+__thread blah=0;
+int blah2=0;
+NETAPI_SPINLOCK_T spin_test;
+
+pid_t gettid( void )
+{
+ return syscall( __NR_gettid );
+}
+
+void *thread_routine( void *arg )
+{
+ int i;
+ int proc_num = (int)(long)arg;
+ cpu_set_t set;
+ int v1, v2,v3;
+
+#if 0
+ CPU_ZERO( &set );
+ CPU_SET( proc_num, &set );
+
+ if (sched_setaffinity( gettid(), sizeof( cpu_set_t ), &set ))
+ {
+ perror( "sched_setaffinity" );
+ return NULL;
+ }
+#endif
+
+ for (i = 0; i < INC_TO; i++)
+ {
+
+ v1 = netapi_timing_start();
+ netapi_atomic_add64(&global_int,1LL);
+ v1= netapi_timing_stop() - v1;
+ sched_yield();
+ v2 = netapi_timing_start();
+ blah+=1;
+ v2= netapi_timing_stop() - v2;
+
+ v3 = netapi_timing_start();
+ blah2+=1;
+ v3= netapi_timing_stop() - v3;
+ if(i<10) { printf("thread %d -> a64 costs %d, tls costs %d simple++ costs %d\n", proc_num,v1,v2,v3);}
+ sched_yield();
+ }
+ printf("thead %d -> blah=%d\n",proc_num, blah);
+
+ printf("now try spin lock test. i'm thread %d, about to grab lock \n", proc_num);
+
+ //now we try the synch_lock_and_test
+ v1 = netapi_timing_start();
+ netapi_spinlock_lock(&spin_test);
+ v2 = netapi_timing_stop();
+ printf("i'm thread %d. I've locked it, val= %d, it took cycles=%d to get it\ngoing to sleep..",proc_num,spin_test,v2-v1);
+ sleep(1);
+ printf(" i'm back. i'm thread %d. i'm unlocking now\n",proc_num);
+ netapi_spinlock_unlock(&spin_test);
+ return NULL;
+}
+
+int main()
+{
+ int procs = 0;
+ int i;
+ pthread_t *thrs;
+ printf("at start up\n");
+
+ // Getting number of CPUs
+ procs = (int)sysconf( _SC_NPROCESSORS_ONLN );
+ if (procs < 0)
+ {
+ perror( "sysconf" );
+ return -1;
+ }
+ printf(" num cpus = %d\n",procs);
+ if (procs==1) {procs+=1; printf("adding 2nd 'core' \n");}
+ thrs = malloc( sizeof( pthread_t ) * procs );
+ if (thrs == NULL)
+ {
+ perror( "malloc" );
+ return -1;
+ }
+
+ //initialize spinlock
+ netapi_spinlock_init(&spin_test);
+ printf( "Starting %d threads...\n", procs );
+
+ for (i = 0; i < procs; i++)
+ {
+ if (pthread_create( &thrs[i], NULL, thread_routine,
+ (void *)(long)i ))
+ {
+ perror( "pthread_create" );
+ procs = i;
+ break;
+ }
+ }
+
+ for (i = 0; i < procs; i++)
+ pthread_join( thrs[i], NULL );
+
+ free( thrs );
+
+ printf( "global_int value is: %lld bare global_int is %d\n",
+ global_int.val, blah2 );
+ printf( "Expected value is: %d\n", INC_TO * procs );
+
+ return 0;
+}
index 9db33e52ce0a74c6e8bd1a22feb4faa4486bda86..2324d52f9a46f2636a96bf9c367aea19f2cf9d43 100755 (executable)
-/*\r
-\r
-Copyright (c) 2005, Simon Howard\r
-All rights reserved.\r
-\r
-Redistribution and use in source and binary forms, with or without \r
-modification, are permitted provided that the following conditions \r
-are met:\r
-\r
- * Redistributions of source code must retain the above copyright \r
- notice, this list of conditions and the following disclaimer.\r
- * Redistributions in binary form must reproduce the above copyright \r
- notice, this list of conditions and the following disclaimer in \r
- the documentation and/or other materials provided with the \r
- distribution.\r
- * Neither the name of the C Algorithms project nor the names of its \r
- contributors may be used to endorse or promote products derived \r
- from this software without specific prior written permission.\r
-\r
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \r
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER \r
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT \r
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN \r
-ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
-POSSIBILITY OF SUCH DAMAGE.\r
-\r
- *ALSO: TI modifications made to support binary data keys\r
-*\r
- * Copyright (c) Texas Instruments Incorporated 2010-2011\r
-*/\r
-\r
-/* Trie: fast mapping of strings to values */\r
-\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-#include "trie.h"\r
-\r
-typedef struct _TrieNode TrieNode;\r
-\r
-struct _TrieNode {\r
- void *data;\r
- unsigned int use_count;\r
- TrieNode *next[256];\r
-};\r
-\r
-struct _Trie {\r
- TrieNode *root_node;\r
-};\r
-\r
-static void trie_free_node(TrieNode *node)\r
-{\r
- int i;\r
-\r
- if (node == NULL)\r
- return;\r
- \r
- /* First, free all subnodes */\r
-\r
- for (i=0; i<256; ++i) {\r
- trie_free_node(node->next[i]);\r
- }\r
-\r
- /* Free this node */\r
-\r
- free(node);\r
-}\r
-\r
-Trie *trie_new(void)\r
-{\r
- Trie *new_trie;\r
-\r
- new_trie = (Trie *) malloc(sizeof(Trie));\r
- new_trie->root_node = NULL;\r
-\r
- return new_trie;\r
-}\r
-\r
-void trie_free(Trie *trie)\r
-{\r
- /* Free the subnode, and all others by implication */\r
-\r
- trie_free_node(trie->root_node);\r
-\r
- /* Free the trie */\r
-\r
- free(trie);\r
-}\r
-\r
-void trie_insert(Trie *trie, char *key, int keylen, void *value)\r
-{\r
- TrieNode **rover;\r
- TrieNode *node;\r
- unsigned char *p;\r
- unsigned char c;\r
- int k;\r
-\r
- /* Cannot insert NULL values */\r
-\r
- if (value == NULL) {\r
- return;\r
- }\r
-\r
- /* Search down the trie until we reach the end of string,\r
- * creating nodes as necessary */\r
-\r
- rover = &trie->root_node;\r
- p = (unsigned char *) key;\r
-\r
- for (k=0;;) {\r
-\r
- node = *rover;\r
-\r
- if (node == NULL) {\r
- \r
- /* Node does not exist, so create it */\r
-\r
- node = (TrieNode *) malloc(sizeof(TrieNode));\r
- memset(node, 0, sizeof(TrieNode));\r
-\r
- /* Link in to the trie */\r
-\r
- *rover = node;\r
- }\r
-\r
- /* One more use of this node */\r
-\r
- ++node->use_count;\r
-\r
- /* Current character */\r
-\r
- c = *p;\r
-\r
- /* Reached the end of string? If so, we're finished. */\r
-\r
- if (k>=keylen) {\r
-\r
- /* Set the data at the node we have reached */\r
-\r
- node->data = value;\r
-\r
- break;\r
- }\r
-\r
- /* Advance to the next node in the chain */\r
-\r
- rover = &node->next[c];\r
- ++p; \r
- k+=1;\r
- }\r
-}\r
-\r
-void trie_remove(Trie *trie, char *key, int keylen)\r
-{\r
- TrieNode *node;\r
- TrieNode *next;\r
- TrieNode **last_next_ptr;\r
- unsigned char *p;\r
- unsigned char c;\r
- int k=0;\r
- \r
- /* First, search down to the ending node so that the data can\r
- * be removed. */\r
-\r
- /* Search down the trie until the end of string is reached */\r
-\r
- node = trie->root_node;\r
-\r
- for (p=(unsigned char *) key, k=0; k<keylen; ++p, k+=1) {\r
-\r
- if (node == NULL) {\r
- /* Not found in the tree. Return. */\r
-\r
- return;\r
- }\r
-\r
- /* Jump to the next node */\r
-\r
- c = *p;\r
- node = node->next[c];\r
- }\r
-\r
- /* Remove the data at this node */\r
-\r
- node->data = NULL;\r
-\r
- /* Now traverse the tree again as before, decrementing the use\r
- * count of each node. Free back nodes as necessary. */\r
-\r
- node = trie->root_node;\r
- last_next_ptr = &trie->root_node;\r
- p = key;\r
-\r
- for (k=0;;k++) {\r
-\r
- /* Find the next node */\r
- \r
- c = *p;\r
- next = node->next[c];\r
-\r
- /* Free this node if necessary */\r
-\r
- --node->use_count;\r
-\r
- if (node->use_count <= 0) {\r
- free(node);\r
-\r
- /* Set the "next" pointer on the previous node to NULL,\r
- * to unlink the free'd node from the tree. This only\r
- * needs to be done once in a remove. After the first\r
- * unlink, all further nodes are also going to be\r
- * free'd. */\r
-\r
- if (last_next_ptr != NULL) {\r
- *last_next_ptr = NULL;\r
- last_next_ptr = NULL;\r
- }\r
- }\r
- \r
- /* Go to the next character or finish */\r
-\r
- if (k>=keylen) {\r
- break;\r
- } else {\r
- ++p;\r
- }\r
-\r
- /* If necessary, save the location of the "next" pointer\r
- * so that it may be set to NULL on the next iteration if\r
- * the next node visited is freed. */\r
-\r
- if (last_next_ptr != NULL) {\r
- last_next_ptr = &node->next[c];\r
- }\r
- \r
- /* Jump to the next node */\r
-\r
- node = next;\r
- }\r
-}\r
-\r
-void *trie_lookup(Trie *trie, char *key, int keylen)\r
-{\r
- TrieNode *node;\r
- unsigned char *p;\r
- unsigned char c;\r
- int k=0;\r
-\r
- /* Search down the trie until the end of string is found */\r
- \r
- node = trie->root_node;\r
- p = (unsigned char *) key;\r
-\r
- while (k<keylen ) {\r
- if (node == NULL) {\r
- /* Not found - reached end of branch */\r
-\r
- return NULL;\r
- }\r
-\r
- /* Advance to the next node in the chain, next character */\r
-\r
- c = *p;\r
- node = node->next[c];\r
- ++p;\r
- k+=1;\r
- }\r
- /* bug! */\r
- \r
- return (node ? node->data : NULL);\r
-\r
-}\r
-\r
-int trie_num_entries(Trie *trie)\r
-{\r
- /* To find the number of entries, simply look at the use count\r
- * of the root node. */\r
-\r
- if (trie->root_node == NULL) {\r
- return 0;\r
- } else {\r
- return trie->root_node->use_count;\r
- }\r
-}\r
-\r
-//#define TEST\r
-#ifdef TEST\r
-main()\r
-{\r
-Trie * p_trie;\r
-char * p_res;\r
-p_trie = trie_new();\r
-if (!p_trie) {printf("trie alloc failed\n"); exit(1);}\r
-\r
-trie_insert(p_trie,"key1","this is key 1");\r
-trie_insert(p_trie,"key12","this is key 2");\r
-trie_insert(p_trie,"key3","this is key 3");\r
-trie_insert(p_trie,"key4","this is key 4");\r
-\r
-p_res= trie_lookup(p_trie,"key1");\r
-printf("lookup %s = %s\n", "key1", p_res ? p_res : "not found");\r
-\r
-p_res= trie_lookup(p_trie,"key12");\r
-printf("lookup %s = %s\n", "key2", p_res ? p_res : "not found");\r
-\r
-p_res= trie_lookup(p_trie,"key3");\r
-printf("lookup %s = %s\n", "key3", p_res ? p_res : "not found");\r
-\r
-p_res= trie_lookup(p_trie,"key4");\r
-printf("lookup %s = %s\n", "key4", p_res ? p_res : "not found");\r
-\r
-p_res= trie_lookup(p_trie,"key5");\r
-printf("lookup %s = %s\n", "key5", p_res ? p_res : "not found");\r
-\r
-p_res= trie_lookup(p_trie,"k5");\r
-printf("lookup %s = %s\n", "k5", p_res ? p_res : "not found");\r
-\r
-trie_free(p_trie);\r
-\r
-}\r
-#endif\r
+/*
+
+Copyright (c) 2005, Simon Howard
+All rights reserved.
+
+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 the C Algorithms project 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.
+
+ *ALSO: TI modifications made to support binary data keys
+*
+ * Copyright (c) Texas Instruments Incorporated 2010-2011
+*/
+
+/* Trie: fast mapping of strings to values */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "trie.h"
+
+typedef struct _TrieNode TrieNode;
+
+struct _TrieNode {
+ void *data;
+ unsigned int use_count;
+ TrieNode *next[256];
+};
+
+struct _Trie {
+ TrieNode *root_node;
+};
+
+static void trie_free_node(TrieNode *node)
+{
+ int i;
+
+ if (node == NULL)
+ return;
+
+ /* First, free all subnodes */
+
+ for (i=0; i<256; ++i) {
+ trie_free_node(node->next[i]);
+ }
+
+ /* Free this node */
+
+ free(node);
+}
+
+Trie *trie_new(void)
+{
+ Trie *new_trie;
+
+ new_trie = (Trie *) malloc(sizeof(Trie));
+ new_trie->root_node = NULL;
+
+ return new_trie;
+}
+
+void trie_free(Trie *trie)
+{
+ /* Free the subnode, and all others by implication */
+
+ trie_free_node(trie->root_node);
+
+ /* Free the trie */
+
+ free(trie);
+}
+
+void trie_insert(Trie *trie, char *key, int keylen, void *value)
+{
+ TrieNode **rover;
+ TrieNode *node;
+ unsigned char *p;
+ unsigned char c;
+ int k;
+
+ /* Cannot insert NULL values */
+
+ if (value == NULL) {
+ return;
+ }
+
+ /* Search down the trie until we reach the end of string,
+ * creating nodes as necessary */
+
+ rover = &trie->root_node;
+ p = (unsigned char *) key;
+
+ for (k=0;;) {
+
+ node = *rover;
+
+ if (node == NULL) {
+
+ /* Node does not exist, so create it */
+
+ node = (TrieNode *) malloc(sizeof(TrieNode));
+ memset(node, 0, sizeof(TrieNode));
+
+ /* Link in to the trie */
+
+ *rover = node;
+ }
+
+ /* One more use of this node */
+
+ ++node->use_count;
+
+ /* Current character */
+
+ c = *p;
+
+ /* Reached the end of string? If so, we're finished. */
+
+ if (k>=keylen) {
+
+ /* Set the data at the node we have reached */
+
+ node->data = value;
+
+ break;
+ }
+
+ /* Advance to the next node in the chain */
+
+ rover = &node->next[c];
+ ++p;
+ k+=1;
+ }
+}
+
+void trie_remove(Trie *trie, char *key, int keylen)
+{
+ TrieNode *node;
+ TrieNode *next;
+ TrieNode **last_next_ptr;
+ unsigned char *p;
+ unsigned char c;
+ int k=0;
+
+ /* First, search down to the ending node so that the data can
+ * be removed. */
+
+ /* Search down the trie until the end of string is reached */
+
+ node = trie->root_node;
+
+ for (p=(unsigned char *) key, k=0; k<keylen; ++p, k+=1) {
+
+ if (node == NULL) {
+ /* Not found in the tree. Return. */
+
+ return;
+ }
+
+ /* Jump to the next node */
+
+ c = *p;
+ node = node->next[c];
+ }
+
+ /* Remove the data at this node */
+
+ node->data = NULL;
+
+ /* Now traverse the tree again as before, decrementing the use
+ * count of each node. Free back nodes as necessary. */
+
+ node = trie->root_node;
+ last_next_ptr = &trie->root_node;
+ p = key;
+
+ for (k=0;;k++) {
+
+ /* Find the next node */
+
+ c = *p;
+ next = node->next[c];
+
+ /* Free this node if necessary */
+
+ --node->use_count;
+
+ if (node->use_count <= 0) {
+ free(node);
+
+ /* Set the "next" pointer on the previous node to NULL,
+ * to unlink the free'd node from the tree. This only
+ * needs to be done once in a remove. After the first
+ * unlink, all further nodes are also going to be
+ * free'd. */
+
+ if (last_next_ptr != NULL) {
+ *last_next_ptr = NULL;
+ last_next_ptr = NULL;
+ }
+ }
+
+ /* Go to the next character or finish */
+
+ if (k>=keylen) {
+ break;
+ } else {
+ ++p;
+ }
+
+ /* If necessary, save the location of the "next" pointer
+ * so that it may be set to NULL on the next iteration if
+ * the next node visited is freed. */
+
+ if (last_next_ptr != NULL) {
+ last_next_ptr = &node->next[c];
+ }
+
+ /* Jump to the next node */
+
+ node = next;
+ }
+}
+
+void *trie_lookup(Trie *trie, char *key, int keylen)
+{
+ TrieNode *node;
+ unsigned char *p;
+ unsigned char c;
+ int k=0;
+
+ /* Search down the trie until the end of string is found */
+
+ node = trie->root_node;
+ p = (unsigned char *) key;
+
+ while (k<keylen ) {
+ if (node == NULL) {
+ /* Not found - reached end of branch */
+
+ return NULL;
+ }
+
+ /* Advance to the next node in the chain, next character */
+
+ c = *p;
+ node = node->next[c];
+ ++p;
+ k+=1;
+ }
+ /* bug! */
+
+ return (node ? node->data : NULL);
+
+}
+
+int trie_num_entries(Trie *trie)
+{
+ /* To find the number of entries, simply look at the use count
+ * of the root node. */
+
+ if (trie->root_node == NULL) {
+ return 0;
+ } else {
+ return trie->root_node->use_count;
+ }
+}
+
+//#define TEST
+#ifdef TEST
+main()
+{
+Trie * p_trie;
+char * p_res;
+p_trie = trie_new();
+if (!p_trie) {printf("trie alloc failed\n"); exit(1);}
+
+trie_insert(p_trie,"key1","this is key 1");
+trie_insert(p_trie,"key12","this is key 2");
+trie_insert(p_trie,"key3","this is key 3");
+trie_insert(p_trie,"key4","this is key 4");
+
+p_res= trie_lookup(p_trie,"key1");
+printf("lookup %s = %s\n", "key1", p_res ? p_res : "not found");
+
+p_res= trie_lookup(p_trie,"key12");
+printf("lookup %s = %s\n", "key2", p_res ? p_res : "not found");
+
+p_res= trie_lookup(p_trie,"key3");
+printf("lookup %s = %s\n", "key3", p_res ? p_res : "not found");
+
+p_res= trie_lookup(p_trie,"key4");
+printf("lookup %s = %s\n", "key4", p_res ? p_res : "not found");
+
+p_res= trie_lookup(p_trie,"key5");
+printf("lookup %s = %s\n", "key5", p_res ? p_res : "not found");
+
+p_res= trie_lookup(p_trie,"k5");
+printf("lookup %s = %s\n", "k5", p_res ? p_res : "not found");
+
+trie_free(p_trie);
+
+}
+#endif
diff --git a/ti/runtime/netapi/test/udpif.c b/ti/runtime/netapi/test/udpif.c
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ *
+ * udpIf.c - provides udp
+ *
+ */
+//#define BENCHMARK
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+
+int nSent=0;
+
+#ifdef BENCHMARK
+struct timeval stime,mtime,etime;
+#endif
+
+#define SENDSZ 1396
+int SendSize=SENDSZ;
+
+#define MAIN_NEEDED
+#ifdef MAIN_NEEDED
+/******************************************************************************
+ main
+*******************************************************************************/
+/* argv[1] = S for Send, R for Receive
+ argv[2] = fileName
+ argv[3] = port
+ argv[4] = ipAddress
+ argv[5] = send size
+*/
+main(argc,argv)
+int argc;
+char **argv;
+{
+int sending = 0;
+char fileName[256];
+int port;
+char ipAddress[64];
+ if (argc < 4)
+ {
+ printf ("usage:udpIf S|R fileName port [ipAddress] [send size]\n");
+ exit(-1);
+ }
+ sending = (*argv[1] == 'S') ? 1 : 0;
+ strcpy(fileName,argv[2]);
+ port = atoi(argv[3]);
+ if (argc >= 5)
+ strcpy(ipAddress,argv[4]);
+ else
+ strcpy(ipAddress,"");
+ if (argc ==6) SendSize=atoi(argv[5]);
+ if (SendSize > SENDSZ) SendSize=SENDSZ;
+ udpif(sending,fileName,port,ipAddress);
+}
+#endif
+char startstring[]="start";
+char endstring[]="done";
+/******************************************************************************
+ udpif
+*******************************************************************************/
+udpif(sending,fileName,port,ipAddress)
+int sending;
+char *fileName;
+int port;
+char *ipAddress;
+{
+struct sockaddr_in addr,fraddr;
+int addrlen, fd, cnt;
+socklen_t fraddrlen;
+char message[SENDSZ+3];
+int numTries = 0;
+#define MAX_TRIES 5
+int rc;
+int sstate=0;
+int total, rtotal;
+total=rtotal=0;
+ if (sending)
+ {
+ int inFile;
+ inFile = open(fileName,O_RDONLY);
+ if (inFile < 0)
+ {
+ printf ("Can't read %s in tcpIf\n",fileName);
+ exit(-1);
+ }
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ printf ("socket is %d\n",fd);
+ if (fd < 0)
+ {
+ perror("socket");
+ exit(1);
+ }
+ bzero(&addr, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+ addr.sin_port = 0;
+ addrlen = sizeof(addr);
+ rc = bind(fd, &addr, sizeof(addr));
+ printf ("Sender:bind rc is %d\n",rc);
+ if (rc < 0)
+ {
+ perror("bind");
+ exit(1);
+ }
+ addr.sin_addr.s_addr = inet_addr(ipAddress);
+ addr.sin_port = htons(port);
+ printf("dbg: %x %x\n", addr.sin_addr.s_addr, addr.sin_port);
+#ifdef BENCHMARK
+ sendto(fd,
+ startstring,
+ strlen(startstring)+1,
+ 0,&addr,sizeof(addr));
+#endif
+ while(1)
+ {
+ char *mPtr;
+ int len;
+ int count = read(inFile,message,/*4096*/ /*SENDSZ*/SendSize);
+#ifndef BENCHMARK
+ //printf ("Sender:in count is %d\n",count);
+#endif
+ if (count == 0)
+ {
+ close(inFile);
+#ifdef BENCHMARK
+ sendto(fd,
+ endstring,
+ strlen(endstring)+1,
+ 0,&addr,sizeof(addr));
+
+ sendto(fd,
+ endstring,
+ strlen(endstring)+1,
+ 0,&addr,sizeof(addr));
+ sendto(fd,
+ endstring,
+ strlen(endstring)+1,
+ 0,&addr,sizeof(addr));
+ printf("sending done %d\n",nSent);
+ sleep(1);
+#endif
+ printf("sending done %d\n",nSent);
+
+ break;
+ }
+ mPtr = message;
+ len = count==-1 ? 5: count;
+ do {
+ cnt = sendto(fd,
+ mPtr,
+ len,
+ 0,&addr,sizeof(addr));
+#ifndef BENCHMARK
+ // printf ("Sender:sendto count is %d\n",cnt);
+#endif
+ if (cnt < 0)
+ {
+ close(inFile);
+ perror("sendto");
+ exit(1);
+ }
+ nSent+=1;
+ mPtr += cnt;
+ len -= cnt;
+ } while(len > 0);
+ }
+ }
+ else
+ {
+ /* receive */
+ int outFile;
+ int newSocket;
+ int rc;
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ printf ("socket is %d\n",fd);
+ if (fd < 0)
+ {
+ perror("socket");
+ exit(1);
+ }
+ bzero(&addr, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_port = htons(port);
+ addrlen = sizeof(addr);
+ rc = bind(fd, &addr, sizeof(addr));
+ printf ("Receiver:bind is %d\n",rc);
+ if (rc < 0)
+ {
+ perror("bind");
+ exit(1);
+ }
+ /*outFile = open(fileName,O_WRONLY | O_CREAT);
+ if (outFile < 0)
+ {
+ printf ("Can't write to %s in tcpIf\n",fileName);
+ exit(-1);
+ }*/
+ memset(&fraddr,0,sizeof(fraddr));
+ fraddr.sin_family= AF_INET;
+ fraddrlen = sizeof(fraddr);
+#ifdef BENCHMARK
+ gettimeofday(&stime, 0 );
+ printf("rcv start @ %d: %d\n",stime.tv_sec, stime.tv_usec);
+
+#endif
+ while(1)
+ {
+#ifdef BENCHMARK
+
+ gettimeofday(&mtime, 0 );
+ if(rtotal >= 10000000)
+ {
+ printf("rcv mtime @ %d: %d %d %d\n",mtime.tv_sec, mtime.tv_usec,total, rtotal);
+ rtotal=0;
+ }
+#endif
+ cnt = recvfrom(fd,
+ message,
+ sizeof(message),
+ 0,
+ NULL,
+ &fraddrlen);
+ //printf ("Receiver:recv count = %d\n",cnt);
+ if (cnt == 0)
+ {
+ /*close(outFile);*/
+ continue;
+ }
+ if (cnt < 0)
+ {
+ /*close(outFile);*/
+ perror("recvfrom");
+ exit(1);
+ }
+ rtotal+=cnt;
+ total+=cnt;
+
+ message[cnt+1] = '\0';
+#ifndef BENCHMARK
+ printf("rcvd %s\n",message);
+#else
+ if (strcmp("done",message)==0)
+ {
+ time_t blah1;
+ suseconds_t blah2;
+ gettimeofday(&etime, 0 );
+ blah1= (etime.tv_usec>stime.tv_usec) ?
+ etime.tv_sec-stime.tv_sec :
+ etime.tv_sec-stime.tv_sec-1;
+ blah2 = (etime.tv_usec>stime.tv_usec) ?
+ etime.tv_usec-stime.tv_usec :
+ 1000000-stime.tv_usec+etime.tv_usec;
+ printf("DONE @ %d: %d {%d %d}\n",etime.tv_sec, etime.tv_usec,
+ blah1, blah2 );
+ gettimeofday(&etime, 0 );
+ }
+ if (strcmp("start",message)==0)
+ {
+ gettimeofday(&stime, 0 );
+ printf("START @ %d: %d\n",stime.tv_sec, stime.tv_usec);
+ }
+
+#endif
+ }
+ }
+}