Adding netapi dpi demo files
authorTinku Mannan <tmannan@ti.com>
Tue, 5 Aug 2014 15:13:32 +0000 (11:13 -0400)
committerTinku Mannan <tmannan@ti.com>
Tue, 5 Aug 2014 18:07:01 +0000 (14:07 -0400)
ti/runtime/netapi/demo/build/Makefile [new file with mode: 0755]
ti/runtime/netapi/demo/src/Makefile [new file with mode: 0755]
ti/runtime/netapi/demo/src/navl_external_posix.c [new file with mode: 0755]
ti/runtime/netapi/demo/src/navl_wrapper.c [new file with mode: 0755]
ti/runtime/netapi/demo/src/navl_wrapper.h [new file with mode: 0755]
ti/runtime/netapi/demo/src/netapi_dpi_demo.c [new file with mode: 0755]
ti/runtime/netapi/demo/src/netapi_dpi_demo.h [new file with mode: 0755]

diff --git a/ti/runtime/netapi/demo/build/Makefile b/ti/runtime/netapi/demo/build/Makefile
new file mode 100755 (executable)
index 0000000..7194cc4
--- /dev/null
@@ -0,0 +1,113 @@
+#
+empty =
+space =$(empty) $(empty)
+
+export ARMV7OBJDIR ?= ./obj
+export ARMV7BINDIR ?= ./bin
+export ARMV7LIBDIR ?= ./lib
+export ARMV7SALIBDIR ?= ./lib
+
+DPI_DEMO_SRC_DIR ?= $(PWD)
+# INCLUDE Directories
+SA_INSTALL_PATH ?= $(PDK_INSTALL_PATH)/ti/drv/sa
+QMSS_INC_DIR ?= $(PDK_INSTALL_PATH)/ti/drv/qmss
+CPPI_INC_DIR ?= $(PDK_INSTALL_PATH)/ti/drv/cppi
+RM_INC_DIR ?= $(PDK_INSTALL_PATH)/ti/drv/rm
+NETAPI_SRC_DIR ?= $(TRANS_SDK_INSTALL_PATH)/ti/runtime/netapi
+NETAPI_INC_DIR ?=  $(TRANS_SDK_INSTALL_PATH)
+HPLIB_INC_DIR ?=  $(HPLIB_INSTALL_PATH)
+NWAL_INSTALL_PATH ?= $(PDK_INSTALL_PATH)/ti/drv/nwal
+PKTLIB_INSTALL_PATH ?= $(PDK_INSTALL_PATH)/ti/runtime/pktlib
+
+
+ifndef NAVL_INSTALL_PATH
+ $(error  NAVL_INSTALL_PATH is undefined)
+else
+NAVL_INSTALL_PATH ?= /home/a0868410/git
+NAVL_LIB_DIR ?= $(NAVL_INSTALL_PATH)/navl/lib
+NAVL_INC_DIR ?= $(NAVL_INSTALL_PATH)
+endif
+
+#TRIE_OBJS=$(ARMV7OBJDIR)/netapi/test/trie.o
+
+NT_RM_OBJS = $(ARMV7OBJDIR)/netapi/utils/sockutils.o  $(ARMV7OBJDIR)/netapi/utils/netapi_util_rm.o
+
+DPI_DEMO_OBJS= $(ARMV7OBJDIR)/netapi/demo/src/netapi_dpi_demo.o $(ARMV7OBJDIR)/netapi/demo/src/navl_wrapper.o $(ARMV7OBJDIR)/netapi/demo/src/navl_external_posix.o
+
+# Support Libraries used by dpi-demo 
+CSL_DEVICE ?= -DDEVICE_K2E -DNSS_GEN2
+QMSS_LIB = -lqmss
+CPPI_LIB = -lcppi
+PA_LIB = -lpa2
+NWAL_LIB = -lnwalsa_k2e
+SA_LIB = -lsa
+RM_LIB = -lrm
+PKTLIB_LIB = -lpktlib
+NETAPI_LIB =-lnetapi_k2e
+HP_LIB = -lhplib_k2e
+NAVL_LIB = -lnavl
+
+local_base=/usr/local
+LDFLAGS = -L. -L$(local_base)/lib
+
+LIBS = -static $(QMSS_LIB) $(CPPI_LIB) $(PA_LIB) $(PKTLIB_LIB) $(NETAPI_LIB) $(HP_LIB) $(SA_LIB) $(NWAL_LIB) $(RM_LIB) -Wl,-Bdynamic
+
+LIBS += $(NAVL_LIB) -lstdc++ -lgcc_s
+
+SYSTYPE:=$(shell uname)
+ifeq ($(SYSTYPE), Linux)
+LIBS += -ldl -lm
+else
+LIBS += -lexecinfo
+endif
+
+ifdef CROSS_TOOL_INSTALL_PATH
+## Support backwards compatibility with KeyStone1 approach
+ CC = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)gcc
+ AC = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)as
+ AR = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)ar
+ LD = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)gcc
+endif
+
+INCLUDE = -I. -I$(local_base)/include -I../ -I$(HPLIB_INC_DIR) -I$(NETAPI_INC_DIR) -I$(PDK_INSTALL_PATH) -I$(NWAL_INSTALL_PATH) -I$(PKTLIB_INSTALL_PATH) -I$(SA_INSTALL_PATH) -I$(QMSS_INC_DIR) -I$(CPPI_INC_DIR) -I$(RM_INC_DIR) -I$(NAVL_INC_DIR) $(CSL_DEVICE)
+
+CFLAGS += $(DEBUG_FLAG) -D__ARMv7 -D_VIRTUAL_ADDR_SUPPORT -D__LINUX_USER_SPACE -D_LITTLE_ENDIAN=1 -DNWAL_ENABLE_SA -DMAKEFILE_BUILD -D _GNU_SOURCE
+# Linker options
+INTERNALLINKDEFS = -Wl,--start-group $(LIBS) -Wl,--end-group -lrt -pthread  -L$(ARMV7LIBDIR) -L$(ARMV7SALIBDIR) -L$(NAVL_LIB_DIR)
+
+EXE_NAME=netapi_dpi_demo_$(DEVICE)
+BIN_DIR = $(ARMV7BINDIR)/netapi/demo
+all: demo install
+
+demo: $(ARMV7BINDIR)/netapi/demo/.created $(BIN_DIR)/$(EXE_NAME)
+
+clean:  
+       rm -f $(ARMV7OBJDIR)/netapi/demo/src/*.o
+       rm -f $(ARMV7BINDIR)/netapi/demo/*
+       
+
+#$(ARMV7OBJDIR)/netapi/demo/src/%.o: %.c $(NETAPI_SRC_DIR)/demo/src/%.c $(ARMV7OBJDIR)/netapi/demo/src/.created
+$(ARMV7OBJDIR)/netapi/demo/src/%.o: $(NETAPI_SRC_DIR)/demo/src/%.c $(ARMV7OBJDIR)/netapi/demo/src/.created
+       @echo compiling $<
+       $(CC) -c  $(CFLAGS) $(INCLUDE) $< -o $@
+
+$(ARMV7OBJDIR)/netapi/demo/src/.created:
+       @mkdir -p $(ARMV7OBJDIR)/netapi/demo/src/
+
+$(ARMV7BINDIR)/netapi/demo/.created:
+       @mkdir -p $(ARMV7BINDIR)/netapi/demo/
+
+$(ARMV7BINDIR)/netapi/demo/$(EXE_NAME): $(NT_RM_OBJS) $(DPI_DEMO_OBJS)
+       $(CC) $(LDFLAGS) $(DPI_DEMO_OBJS) $(NT_RM_OBJS) $(INTERNALLINKDEFS) $(INCLUDE) -o $(BIN_DIR)/$(EXE_NAME)
+
+
+$(ARMV7OBJDIR)/netapi/utils/%.o: $(NETAPI_SRC_DIR)/utils/%.c $(ARMV7OBJDIR)/netapi/utils/.created
+       @echo compiling $<
+       $(CC) -c  $(CFLAGS) $(INCLUDE) $< -o $@
+
+$(ARMV7OBJDIR)/netapi/utils/.created:
+       @mkdir -p $(ARMV7OBJDIR)/netapi/utils/
+
+install:
+       install -d $(INSTALL_BIN_BASE_DIR)
+       install -c -m 755 $(BIN_DIR)/$(EXE_NAME) $(INSTALL_BIN_BASE_DIR)/$(EXE_NAME)
diff --git a/ti/runtime/netapi/demo/src/Makefile b/ti/runtime/netapi/demo/src/Makefile
new file mode 100755 (executable)
index 0000000..aa84b3a
--- /dev/null
@@ -0,0 +1,95 @@
+#
+empty =
+space =$(empty) $(empty)
+
+export ARMV7OBJDIR ?= ./obj
+export ARMV7BINDIR ?= ./bin
+export ARMV7LIBDIR ?= ./lib
+export ARMV7SALIBDIR ?= ./lib
+
+DPI_DEMO_SRC_DIR ?= $(PWD)
+# INCLUDE Directories
+SA_INSTALL_PATH ?= $(PDK_INSTALL_PATH)/ti/drv/sa
+QMSS_INC_DIR ?= $(PDK_INSTALL_PATH)/ti/drv/qmss
+CPPI_INC_DIR ?= $(PDK_INSTALL_PATH)/ti/drv/cppi
+RM_INC_DIR ?= $(PDK_INSTALL_PATH)/ti/drv/rm
+#NETAPI_INC_DIR ?=  $(NETAPI_INSTALL_PATH)/ti/runtime/netapi
+NETAPI_INC_DIR ?=  $(NETAPI_INSTALL_PATH)
+#HPLIB_INC_DIR ?=  $(HPLIB_INSTALL_PATH)/ti/runtime/hplib
+HPLIB_INC_DIR ?=  $(HPLIB_INSTALL_PATH)
+NWAL_INSTALL_PATH ?= $(PDK_INSTALL_PATH)/ti/drv/nwal
+PKTLIB_INSTALL_PATH ?= $(PDK_INSTALL_PATH)/ti/runtime/pktlib
+NAVL_LIB_DIR ?= $(DPI_DEMO_SRC_DIR)/../lib
+# Set NETAPI INSTALL PATH to Transport SDK for default
+
+#NT_RM_OBJS = $(ARMV7OBJDIR)/netapi/utils/sockutils.o  $(ARMV7OBJDIR)/netapi/utils/netapi_util_rm.o
+
+#TRIE_OBJS=$(ARMV7OBJDIR)/netapi/test/trie.o
+
+
+DPI_DEMO_OBJS= $(ARMV7OBJDIR)/dpi_demo_git/src/dpi_demo.o $(ARMV7OBJDIR)/dpi_demo_git/src/navl_wrapper.o $(ARMV7OBJDIR)/dpi_demo_git/src/navl_external_posix.o
+
+# Support Libraries used by dpi-demo 
+CSL_DEVICE ?= -DDEVICE_K2E -DNSS_GEN2
+QMSS_LIB = -lqmss
+CPPI_LIB = -lcppi
+PA_LIB = -lpa2
+NWAL_LIB = -lnwalsa_k2e
+SA_LIB = -lsa
+RM_LIB = -lrm
+PKTLIB_LIB = -lpktlib
+NETAPI_LIB =-lnetapi_k2e
+HP_LIB = -lhplib_k2e
+NAVL_LIB = -lnavl
+
+local_base=/usr/local
+LDFLAGS = -L. -L$(local_base)/lib
+
+LIBS = -static $(QMSS_LIB) $(CPPI_LIB) $(PA_LIB) $(PKTLIB_LIB) $(NETAPI_LIB) $(HP_LIB) $(SA_LIB) $(NWAL_LIB) $(RM_LIB) -Wl,-Bdynamic
+
+LIBS += $(NAVL_LIB) -lstdc++ -lgcc_s
+EXE_EXTN =
+
+SYSTYPE:=$(shell uname)
+ifeq ($(SYSTYPE), Linux)
+LIBS += -ldl -lm
+else
+LIBS += -lexecinfo
+endif
+
+ifdef CROSS_TOOL_INSTALL_PATH
+## Support backwards compatibility with KeyStone1 approach
+ CC = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)gcc
+ AC = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)as
+ AR = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)ar
+ LD = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)gcc
+endif
+
+INCLUDE = -I. -I$(local_base)/include -I../ -I$(HPLIB_INC_DIR) -I$(NETAPI_INC_DIR) -I$(PDK_INSTALL_PATH) -I$(NWAL_INSTALL_PATH) -I$(PKTLIB_INSTALL_PATH) -I$(SA_INSTALL_PATH) -I$(QMSS_INC_DIR) -I$(CPPI_INC_DIR) -I$(RM_INC_DIR) $(CSL_DEVICE)
+
+CFLAGS += $(DEBUG_FLAG) -D__ARMv7 -D_VIRTUAL_ADDR_SUPPORT -D__LINUX_USER_SPACE -D_LITTLE_ENDIAN=1 -DNWAL_ENABLE_SA -DMAKEFILE_BUILD -D _GNU_SOURCE
+# Linker options
+INTERNALLINKDEFS = -Wl,--start-group $(LIBS) -Wl,--end-group -lrt -pthread  -L$(ARMV7LIBDIR) -L$(ARMV7SALIBDIR) -L$(NAVL_LIB_DIR)
+
+all: tests 
+
+tests: $(ARMV7BINDIR)/dpi_demo_git/demo/.created $(ARMV7BINDIR)/dpi_demo_git/demo/dpi_demo_$(DEVICE)
+
+clean: 
+       rm -f $(ARMV7OBJDIR)/dpi_demo/demo/*.o
+       rm -f $(ARMV7BINDIR)/dpi_demo/demo/*
+
+$(ARMV7OBJDIR)/dpi_demo_git/src/%.o: %.c $(ARMV7OBJDIR)/dpi_demo_git/src/.created
+       @echo compiling $<
+       $(CC) -c  $(CFLAGS) $(INCLUDE) $<  -o $@
+
+$(ARMV7OBJDIR)/dpi_demo_git/src/.created:
+       @mkdir -p $(ARMV7OBJDIR)/dpi_demo_git/src/
+
+$(ARMV7BINDIR)/dpi_demo_git/demo/.created:
+       @mkdir -p $(ARMV7BINDIR)/dpi_demo_git/demo/
+
+$(ARMV7BINDIR)/dpi_demo_git/demo/dpi_demo_$(DEVICE): $(DPI_DEMO_OBJS)
+       echo 'test123'
+       #$(CC) $(LDFLAGS) $(DPI_DEMO_OBJS) $(INTERNALLINKDEFS) $(INCLUDE) -rdynamic ../lib/libnavl.so -o $(ARMV7BINDIR)/dpi_demo_git/demo/dpi_demo_$(DEVICE)$(EXE_EXTN)
+       $(CC) $(LDFLAGS) $(DPI_DEMO_OBJS) $(INTERNALLINKDEFS) $(INCLUDE) -o $(ARMV7BINDIR)/dpi_demo_git/demo/dpi_demo_$(DEVICE)$(EXE_EXTN)
diff --git a/ti/runtime/netapi/demo/src/navl_external_posix.c b/ti/runtime/netapi/demo/src/navl_external_posix.c
new file mode 100755 (executable)
index 0000000..60ceec3
--- /dev/null
@@ -0,0 +1,119 @@
+#include <navl/navl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <math.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+
+int malloc_inst=0;
+int malloc_bytes=0;
+void* our_malloc(size_t n)
+{
+    malloc_inst+=1;
+    malloc_bytes+= n;
+    return (malloc(n));
+}
+int null_log_message(const char *level, const char *func, const char *format, ... )
+{
+    return 0;
+}
+
+int printf_log_message(const char *level, const char *func, const char *format, ... )
+{
+    int res = 0;
+    char buf[4096];
+    va_list va;
+    va_start(va, format);
+
+    res = snprintf(buf, 4096, "%s: %s: ", level, func);
+    res += vsnprintf(buf + res, 4096 - res, format, va);
+        navl_diag_printf(buf);
+    va_end(va);
+    return res;
+}
+
+void bind_navl_externals()
+{
+    /* memory allocation */
+    navl_malloc_local = our_malloc;
+    navl_free_local = free;
+    navl_malloc_shared = our_malloc;
+    navl_free_shared = free;
+
+    /* ctype */
+    navl_islower = islower;
+    navl_isupper = isupper;
+    navl_tolower = tolower;
+    navl_toupper = toupper;
+    navl_isalnum = isalnum;
+    navl_isspace = isspace;
+    navl_isdigit = isdigit;
+
+    /* string functions */
+    navl_atoi = atoi;
+    navl_memcpy = memcpy;
+    navl_memcmp = memcmp;
+    navl_memset = memset;
+    navl_strcasecmp = strcasecmp;
+    navl_strchr = (const char* (*)(const char*, int))strchr;
+    navl_strrchr = (const char* (*)(const char*, int))strrchr;
+    navl_strcmp = strcmp;
+    navl_strncmp = strncmp;
+    navl_strcpy = strcpy;
+    navl_strncpy = strncpy;
+    navl_strerror = strerror;
+    navl_strftime = (size_t (*)(char*, size_t, const char*, const struct navl_tm*))strftime;
+    navl_strlen = strlen;
+    navl_strpbrk = (const char* (*)(const char*, const char*))strpbrk;
+    navl_strstr = (const char* (*)(const char*, const char*))strstr;
+    navl_strtol = strtol;
+
+    /* input/output */
+    navl_printf = printf;
+    navl_sprintf = sprintf;
+    navl_snprintf = snprintf;
+    navl_sscanf = sscanf;
+    navl_putchar = putchar;
+    navl_puts = puts;
+    navl_diag_printf = printf;
+
+    /* time */
+    navl_gettimeofday = (int (*)(struct navl_timeval*, void*))gettimeofday;
+    navl_mktime = (navl_time_t (*)(struct navl_tm*))mktime;
+
+    /* math */
+    navl_log = log;
+    navl_fabs = fabs;
+
+#if 0
+    /* network */
+#ifndef __mips__
+    navl_htonl = htonl;
+    navl_htons = htons;
+    navl_ntohl = ntohl;
+    navl_ntohs = ntohs;
+#endif
+#endif
+    /* system */
+    navl_abort = abort;
+    navl_get_thread_id = (unsigned long (*)(void))pthread_self;
+
+    /* navl specific */
+#ifdef DEBUG
+    navl_log_message = printf_log_message;
+#else
+    navl_log_message = null_log_message;
+#endif
+}
+
diff --git a/ti/runtime/netapi/demo/src/navl_wrapper.c b/ti/runtime/netapi/demo/src/navl_wrapper.c
new file mode 100755 (executable)
index 0000000..e282b12
--- /dev/null
@@ -0,0 +1,897 @@
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <getopt.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdarg.h>
+#include "ti/runtime/hplib/hplib.h"
+#include "navl_wrapper.h"
+/* timing */
+
+#define netapi_timing_start hplib_mUtilGetPmuCCNT
+
+extern int malloc_inst;
+
+
+navl_wrapper_cfg_info_t *pNavlCfg;
+void* pShmBase;
+void *pShmEntry;
+
+int free_inst=0;
+extern int malloc_bytes;
+static unsigned long long malloc_cycles;
+static unsigned long long free_cycles;
+static int n_ops=0;
+static int n_class=0;
+static unsigned long min_time=100000000;
+static unsigned long max_time=0;
+static unsigned long long timing=0LL;
+static unsigned long n_err=0;
+static char last_url[256];
+int class=0;
+void clear_pkt_stats();
+void navl_clear_stats(void)
+{
+    n_ops=0;
+    timing=0LL;
+    n_class=0;
+    min_time=100000000;
+    max_time=0;
+    n_err=0;
+    malloc_inst=0; free_inst=0; free_cycles=0LL; malloc_cycles=0LL;
+    clear_pkt_stats();
+}
+void navl_return_stats(int * Pn_ops, int * Pn_class, unsigned long * Pmin_time, unsigned long * Pmax_time, unsigned long long *Ptiming, int * Pmalloc_inst, int *Pmalloc_bytes, int * Pn_err, int *Pfree_inst, unsigned long *Pmalloc_cycles, unsigned long *Pfree_cycles)
+{
+    *Pn_ops=n_ops;
+    *Pn_class=n_class;
+    *Pmin_time=min_time;
+    *Pmax_time=max_time;
+    *Ptiming=timing;
+    *Pmalloc_inst = malloc_inst;
+    *Pmalloc_bytes= malloc_bytes;
+    *Pn_err=n_err;
+    *Pfree_inst = free_inst; 
+    *Pmalloc_cycles= malloc_inst ? malloc_cycles/malloc_inst: 0;
+    *Pfree_cycles= free_inst? free_cycles/free_inst : 0;
+}
+
+//#define MAX_BIN 10
+static long bins[MAX_BIN]={10000, 12500, 15000,17500,20000, 25000,30000,35000,40000,50000};
+static char* binStr[MAX_BIN]={"10K", "12.5K", "15K","17.5K","20K","25K","30K","35K","40K","50K"};
+
+void add2bin(long cycles, long p_bins[])
+{
+    int i;
+    for(i=0;i<MAX_BIN-1;i++)
+      if (cycles<bins[i]) {p_bins[i]+=1;return;}
+     p_bins[MAX_BIN-1] += 1; //max
+}
+
+#if 0
+/* for tracking packet stats */
+typedef struct
+{
+    uint64_t packets;
+    uint64_t bytes;
+    char name[12];
+    uint64_t cycles;
+    uint64_t cycles_nomem;
+    long cycles_nomem_max;
+    long cycles_nomem_min;
+    uint64_t class; //# packets classified
+    long bin_cycles[MAX_BIN];
+} navl_wrapper_pkt_stat_t;
+
+
+
+/* for tracking packets per thread/core basis */
+typedef struct 
+{
+    navl_wrapper_cfg_info_t     navl_cfg;
+    navl_wrapper_pkt_stat_t     stats_pkt[2];
+} navl_wrapper_shm_pkt_stats_t;
+
+
+
+
+/* for tracking memory stats */
+typedef struct
+{
+    int64_t curr;
+    int64_t peak;
+    int64_t fail;
+} navl_wrapper_stat_t;
+
+
+
+
+/* instance variables */
+typedef struct {
+/* handles */
+    navl_handle_t           navl;
+
+    /* configuration */
+    const char             *config_capfile;
+    const char             *config_plugins;
+    int                     config_num_proto;
+    int                     config_conn_id_attr;
+    int                     config_http_attr;
+    int                     config_num_memctx;
+    int                     config_num_memobj;
+
+    /* options */
+    int                     option_dpi;
+    int                     option_simple;
+    int                     option_track_memory;
+    int                     option_limit_memory;
+    int                     option_tunnel;
+    int                     option_realtime_mode;
+    int                     option_verbose;
+
+    /* diagnostics */
+    int                     error_navl;
+
+    /* statistics */
+#define NUM_MEM_CTX 50
+#define NUM_MEM_OBJ 50
+    navl_wrapper_stat_t    stats_mem[NUM_MEM_CTX][NUM_MEM_OBJ];
+    char                    ctx_name[NUM_MEM_CTX][64];
+    char                    obj_name[NUM_MEM_OBJ][64];
+    navl_wrapper_pkt_stat_t *stats_pkt[2];
+    uint64_t                stats_conns;
+
+    /* misc vars */
+    int                     running;
+    int64_t                 alloc_curr;
+    int64_t                 alloc_peak;
+} navl_mcb_t;
+#endif
+
+
+navl_mcb_t *g_reader = NULL;
+const char *g_exename = NULL;
+
+static int  navl_wrapper_init(int argc, char *argv[]);
+static void *navl_wrapper_malloc(size_t);
+static void  navl_wrapper_free(void *);
+static int   navl_wrapper_log_message(const char *level, const char *func, const char *format, ...);
+
+static int navl_classify_callback(navl_handle_t handle, navl_result_t result, navl_state_t state, navl_conn_t conn, void *arg, int error);
+
+static void  navl_wrapper_mem_stat_print();
+
+/* external definitions */
+void bind_navl_externals();
+
+void navl_set_verbose(void)
+{
+    g_reader->option_verbose=!g_reader->option_verbose;
+    printf(">**DPI Now in %s mode\n",g_reader->option_verbose?"verbose":"nonverbose");
+}
+void navl_dump_conn_info()
+{
+navl_diag(g_reader->navl, "TCP", NULL);
+}
+
+
+#define navl_wrapper_error() \
+do { \
+    fprintf(stderr, "%s failed in %s:%u", g_exename, __FUNCTION__, __LINE__); \
+    if (g_reader) { \
+    if (g_reader->error_navl) \
+    fprintf(stderr, " with navl error %s", get_error_string(navl_error_get(g_reader->navl))); \
+    } \
+    fprintf(stderr, "\n"); \
+} while (0)
+
+int navl_setup(void)
+{
+    return (navl_wrapper_init(0, NULL));
+    //return 1;
+}
+
+
+static const char *
+get_state_string(navl_state_t state)
+{
+switch (state)
+    {
+        case NAVL_STATE_INSPECTING:
+            return "INSPECTING";
+        case NAVL_STATE_MONITORING:
+            return "MONITORING";
+        case NAVL_STATE_CLASSIFIED:
+            return "CLASSIFIED";
+        case NAVL_STATE_TERMINATED:
+            return "TERMINATED";
+        default:
+            return "UNKNOWN";
+    }
+}
+
+static const char *
+get_confidence_string(int confidence)
+{
+    switch (confidence)
+    {
+        case 50:
+            return "PORT";
+        case 100:
+            return "DPI";
+        default:
+            return "NONE";
+    }
+}
+
+static const char *
+get_error_string(int error)
+{
+    switch (error)
+    {
+        case 0:
+            return "None";
+        case ENOMEM:
+            return "No memory available";
+        case EPROTO:
+            return "Protocol error";
+        case ENOTCONN:
+            return "No connection allocated";
+        case EEXIST:
+            return "Object exists";
+        case EINVAL:
+            return "Invalid parameter";
+        case ECANCELED:
+            return "Operation cancelled";
+        case ENOENT:
+            return "No such file or directory";
+        case EPROTONOSUPPORT:
+            return "Protocol not supported";
+        default:
+            return "Unknown";
+    }
+}
+
+static int
+navl_wrapper_init(int argc, char *argv[])
+{
+    static navl_mcb_t reader;
+
+    int ret;
+
+    g_reader = &reader;
+
+    g_reader->navl = -1;
+
+    g_reader->config_capfile = NULL;
+    g_reader->config_plugins = "plugins";
+    g_reader->config_num_proto = 0;
+    g_reader->config_conn_id_attr = 0;
+    g_reader->config_http_attr = 0;
+    g_reader->config_num_memctx = NUM_MEM_CTX;
+    g_reader->config_num_memobj = NUM_MEM_OBJ;
+
+    g_reader->option_dpi = 1;
+    g_reader->option_simple = 0;
+    g_reader->option_track_memory = 1;
+    g_reader->option_limit_memory = 0;
+    g_reader->option_realtime_mode = 1;
+    g_reader->option_verbose = 0;
+
+    g_reader->error_navl = 0;
+
+    g_reader->stats_pkt[0] = NULL;
+    g_reader->stats_pkt[1] = NULL;
+    
+    g_reader->stats_conns = 0;
+
+    g_reader->running = 1;
+    g_reader->alloc_curr = 0;
+    g_reader->alloc_peak = 0;
+
+    g_exename = "dpi_demo";
+
+    /* EXTERNAL BINDINGS GO HERE */
+    {
+        /* Bind the platform specific functions. */
+        bind_navl_externals();
+
+        /* Private overrides for this example application. */
+        navl_log_message = navl_wrapper_log_message;
+        if (g_reader->option_track_memory)
+        {
+            navl_malloc_local = navl_wrapper_malloc;
+            navl_free_local = navl_wrapper_free;
+            navl_malloc_shared = navl_wrapper_malloc;
+            navl_free_shared = navl_wrapper_free;
+
+            memset(g_reader->stats_mem, 0, sizeof(g_reader->stats_mem));
+        }
+    }
+
+    /* open the navl library */
+    if ((g_reader->navl = navl_open(g_reader->config_plugins)) == -1)
+        navl_wrapper_error();
+
+    /* set logging level to "error | fatal" */
+    if (navl_config_set(g_reader->navl, "system.loglevel", "48") == -1)
+        navl_wrapper_error();
+
+    /* determine the max protocol index */
+    if ((ret = navl_proto_max_index(g_reader->navl)) == -1)
+    {
+        printf("navl_proto_max_index error\n");
+        navl_wrapper_error();
+    }
+
+    /* the number of protocols is the max + 1 */
+    g_reader->config_num_proto = (ret + 1);
+
+
+
+    /* allocate segment for shared memory for packet stats */
+     /* allocate packet statistics */
+    pShmBase = hplib_shmOpen();
+    if (pShmBase)
+    {
+        if (hplib_shmAddEntry(pShmBase,
+                          sizeof(navl_wrapper_pkt_stat_t)
+                         * g_reader->config_num_proto *NUM_FP_PROCS + sizeof(navl_wrapper_cfg_info_t),
+                         APP_ENTRY_1) != hplib_OK)
+        {
+            printf("navl_per_thread_init failure\n");
+            navl_wrapper_error();
+            return -1;
+        }
+        else
+        {
+            printf("navl_wrapper_init: num proto %d\n", g_reader->config_num_proto);
+            pShmEntry = hplib_shmGetEntry(pShmBase, APP_ENTRY_1);
+            pNavlCfg =  (navl_wrapper_cfg_info_t*)pShmEntry;
+            memset(pNavlCfg,
+                   0,
+                   sizeof(navl_wrapper_pkt_stat_t) * g_reader->config_num_proto *NUM_FP_PROCS+ sizeof(navl_wrapper_cfg_info_t));
+            pNavlCfg =  (navl_wrapper_cfg_info_t*)pShmEntry;
+            pNavlCfg->num_protocols = g_reader->config_num_proto;
+            g_reader->stats_pkt[0] = pShmEntry + sizeof(navl_wrapper_cfg_info_t);
+
+        
+            g_reader->stats_pkt[1] = pShmEntry + sizeof(navl_wrapper_cfg_info_t) +
+                    (sizeof(navl_wrapper_pkt_stat_t)*g_reader->config_num_proto); 
+
+            printf("navl_wrapper_init:  address: 0x%x\n", pShmEntry);
+
+            printf("navl_wrapper_init: stats 0 address: 0x%x\n", &g_reader->stats_pkt[0]);
+
+            printf("navl_wrapper_init: stats 1 address: 0x%x\n", &g_reader->stats_pkt[1]);
+
+        }
+    }
+    return ;
+}
+
+//per thread init. Call this in worker thread context
+int navl_per_thread_init(uint32_t thread_num)
+{
+    int  ret;
+    int c;
+
+     /* initialize this thread for classification */
+    if (navl_init(g_reader->navl))
+    {
+        printf("navl_init error\n");
+        navl_wrapper_error();
+    }
+#if 0
+        /* enable connection tracking */
+        if (navl_attr_enable(g_reader->navl, "conn.id", 1) == -1)
+                navl_wrapper_error();
+
+#ifdef HTTP_ATTRIB
+        /* enable http url */
+        if (navl_attr_enable(g_reader->navl, "http.request.url",1) == -1)
+                navl_wrapper_error();
+#endif
+
+        /* lookup the key for conn.id */
+        if ((g_reader->config_conn_id_attr = navl_attr_key_get(g_reader->navl, "conn.id")) == -1)
+                navl_wrapper_error();
+#ifdef HTTP_ATTRIB
+        /* lookup the key for http.request.host */
+        if ((g_reader->config_http_attr = navl_attr_key_get(g_reader->navl, "http.request.url")) == -1)
+                navl_wrapper_error();
+#endif
+#endif
+    /* simulated realtime */
+    if (g_reader->option_realtime_mode == 2)
+        navl_clock_set_mode(g_reader->navl, 1);
+
+
+#if 0
+    /* determine the max protocol index */
+    if ((ret = navl_proto_max_index(g_reader->navl)) == -1)
+    {
+        printf("navl_proto_max_index error\n");
+        navl_wrapper_error();
+    }
+
+    /* the number of protocols is the max + 1 */
+    g_reader->config_num_proto = (ret + 1);
+#endif
+
+#if 0
+    if ((g_reader->stats_pkt = 
+        (navl_wrapper_pkt_stat_t *)malloc(sizeof(*g_reader->stats_pkt)
+    * (g_reader->config_num_proto))) == NULL)
+    {
+        navl_wrapper_error();
+    }
+    memset(g_reader->stats_pkt, 0, sizeof(*g_reader->stats_pkt) * (g_reader->config_num_proto) * 2);
+#endif
+    /* now fetch all the protocol name ahead of time do we don't have to lookup them up on each packet */
+    for (ret = 0; ret != g_reader->config_num_proto; ret++)
+        navl_proto_get_name(g_reader->navl, ret,
+                            g_reader->stats_pkt[thread_num-1][ret].name,
+                            sizeof(g_reader->stats_pkt[thread_num-1][ret].name));
+
+
+ /* fetch all the memory tag names */
+    for (c = 0; c < NUM_MEM_CTX; c++)
+        navl_memory_ctx_name(g_reader->navl, c, g_reader->ctx_name[c], sizeof(g_reader->ctx_name[c]));
+    for (c = 0; c < NUM_MEM_OBJ; c++)
+        navl_memory_obj_name(g_reader->navl, c, g_reader->obj_name[c], sizeof(g_reader->obj_name[c]));
+
+    return 1;
+}
+
+
+static uint64_t
+msec_time(struct timeval *tv)
+{
+    return ((uint64_t)tv->tv_sec * 1000) + (tv->tv_usec / 1000);
+}
+
+static void
+msec_delay(uint64_t msecs)
+{
+    struct timeval tv = { msecs / 1000, (msecs % 1000) * 1000 };
+    select(0, 0, 0, 0, &tv);
+}
+
+#if 1
+typedef struct
+{
+    const uint8_t *data;
+    uint32_t       size;
+    uint32_t       sequence;
+    int32_t        appidx;
+    uint64_t       connid;
+} navl_wrapper_packet_t;
+#else
+typedef struct
+{
+       const uint8_t    *data;
+       uint32_t          size;
+       uint32_t          sequence;
+       int32_t           appidx;
+       int32_t           num_cb;
+} navl_wrapper_packet_t;
+#endif
+
+
+#if 1
+static int
+navl_classify_callback(navl_handle_t handle,
+                            navl_result_t result,
+                            navl_state_t state,
+                            navl_conn_t conn,
+                            void *arg,
+                            int error)
+{
+    int idx, protoid = 0, confidence = 0;
+    char buf[256] = {0};
+    navl_iterator_t it;
+    navl_wrapper_packet_t *packet = (navl_wrapper_packet_t *)arg;
+    int threadId =Osal_nwalGetProcId();
+
+    packet->appidx = navl_app_get(g_reader->navl, result, &confidence);
+    if((state==NAVL_STATE_CLASSIFIED) ||
+       (state==NAVL_STATE_TERMINATED) ||
+       (state==NAVL_STATE_MONITORING))
+    {
+        n_class+=1;
+        class =1;
+    }
+        else class=0;
+#if 0
+    if (navl_proto_find_index(g_reader->navl, "HTTP") == packet->appidx)
+    {
+        it = navl_proto_find(g_reader->navl, result, navl_proto_find_index(g_reader->navl, "HTTP"));
+        if (navl_proto_valid(g_reader->navl, it))
+            navl_attr_get(g_reader->navl,
+            it, 
+            g_reader->config_http_attr, 
+            &last_url,
+            sizeof(last_url));
+    }
+#endif
+    if (g_reader->option_verbose)
+    {
+        /* Build the stack string */
+        for (idx = 0, it = navl_proto_first(g_reader->navl, result); navl_proto_valid(g_reader->navl, it); navl_proto_next(g_reader->navl, it))
+        {
+            protoid = navl_proto_get_index(g_reader->navl, it);
+            if (!packet->connid)
+            {
+                if (navl_proto_find_index(g_reader->navl, "IP") == protoid)
+                {
+#if 0
+                    navl_attr_get(g_reader->navl, it, g_reader->config_conn_id_attr, &packet->connid, sizeof(packet->connid));
+                    if (packet->connid > g_reader->stats_conns)
+                    g_reader->stats_conns = packet->connid;
+#endif
+                }
+            }
+            idx += sprintf(&buf[idx], "/%s", g_reader->stats_pkt[threadId -1][protoid].name);
+        }
+        printf(" Pkt: %u (%u bytes), Conn: %" PRIu64 ", App: %s (%s), State: %s, Stack: %s, Error: %s\n", packet->sequence
+        , packet->size, packet->connid, g_reader->stats_pkt[threadId -1][packet->appidx].name
+        , get_confidence_string(confidence), get_state_string(state), buf, get_error_string(error));
+    }
+
+    /* Continue tracking the flow */
+    return 0;
+}
+#else
+static int
+navl_classify_callback(navl_handle_t handle,
+                            navl_result_t result,
+                            navl_state_t state,
+                            navl_conn_t conn,
+                            void *arg,
+                            int error)
+{
+       int idx, protoid = 0, confidence = 0;
+       char buf[256] = {0};
+       navl_iterator_t it;
+       navl_conn_id_t conn_id = navl_conn_id_get(handle, conn);
+       navl_wrapper_packet_t *packet = (navl_wrapper_packet_t *)arg;
+
+       /* Always display the outer packet; optionally display encapsulated data */
+       if (!packet->num_cb || g_reader->option_tunnel)
+       {
+               packet->appidx = navl_app_get(g_reader->navl, result, &confidence);
+
+               if (g_reader->option_verbose)
+               {
+                       if (conn_id > g_reader->stats_conns)
+                               g_reader->stats_conns = conn_id;
+
+                       /* Build the stack string */
+                       for (idx = 0, it = navl_proto_first(g_reader->navl, result); navl_proto_valid(g_reader->navl, it); navl_proto_next(g_reader->navl, it))
+                       {
+                               protoid = navl_proto_get_index(g_reader->navl, it);
+                               idx += sprintf(&buf[idx], "/%s", g_reader->stats_pkt[threadId -1][protoid].name);
+                       }
+
+                       printf(" Pkt: %u (%u bytes), Conn: %" PRIu64 ", App: %s (%s), State: %s, Stack: %s, Error: %s\n"
+                               , packet->sequence, packet->size, conn_id, g_reader->stats_pkt[threadId -1][packet->appidx].name
+                               , get_confidence_string(confidence), get_state_string(state), buf, get_error_string(error));
+               }
+       }
+
+       packet->num_cb++;
+
+       /* Continue tracking the flow */
+       return 0;
+}
+#endif
+
+//process the packet
+__thread navl_wrapper_packet_t packet = { NULL, 0, 0 };
+int navl_process_pkt(unsigned char *p_pkt, int len)
+{
+    volatile unsigned long v1;
+    volatile unsigned long v2;
+    unsigned long temp;
+    uint64_t last = 0;
+    uint64_t next = 0;
+    unsigned long long mf1;
+    unsigned long long mf2;
+    mf1= malloc_cycles+free_cycles;
+    v1 = netapi_timing_start();
+    int threadId =Osal_nwalGetProcId();
+
+/* update the current packet */
+    packet.sequence++;
+    packet.size = len;
+    packet.appidx = 0;
+    //packet.connid = 0;
+    packet.data=p_pkt;
+
+    /* "real" realtime */
+    if (g_reader->option_realtime_mode == 1)
+    {
+        //next = msec_time(0LL);//dal -> get ts here
+        next=0LL;
+        if (last)
+        msec_delay(next - last);
+        last = next;
+    }
+    if (navl_classify(g_reader->navl,
+                      NAVL_ENCAP_ETH,
+                      packet.data,
+                      packet.size,
+                      NULL,
+                      0,
+                      navl_classify_callback,
+                      &packet) == -1)
+    printf(" Pkt: %u (%u bytes), Error: %s\n", packet.sequence,
+                                               packet.size,
+                get_error_string(navl_error_get(g_reader->navl)));
+
+    /* Update the stats. If classification was not enabled, then the appidx will be 0 and all packets
+     * captured will be accumulated there */
+    g_reader->stats_pkt[threadId -1][packet.appidx].packets++;
+    g_reader->stats_pkt[threadId -1][packet.appidx].bytes += packet.size;
+    if(class)  g_reader->stats_pkt[threadId -1][packet.appidx].class++;
+    //update timing
+    v2 = netapi_timing_start();
+    temp=v2-v1;
+    mf2= malloc_cycles+free_cycles;
+    timing+= (unsigned long long) temp;
+    g_reader->stats_pkt[threadId -1][packet.appidx].cycles += (unsigned long long) temp;
+    g_reader->stats_pkt[threadId -1][packet.appidx].cycles_nomem += ((unsigned long long) temp - (mf2-mf1));
+
+    if (g_reader->stats_pkt[threadId -1][packet.appidx].cycles_nomem_min > (temp - (unsigned long)(mf2-mf1)))
+        g_reader->stats_pkt[threadId -1][packet.appidx].cycles_nomem_min = (temp - (unsigned long)(mf2-mf1));
+
+    if (g_reader->stats_pkt[threadId -1][packet.appidx].cycles_nomem_max < (temp - (unsigned long)(mf2-mf1)) )
+        g_reader->stats_pkt[threadId -1][packet.appidx].cycles_nomem_max = (temp - (unsigned long)(mf2-mf1));
+
+    add2bin((temp - (unsigned long)(mf2-mf1)),&g_reader->stats_pkt[threadId -1][packet.appidx].bin_cycles[0]); 
+    n_ops+=1;
+    if (temp>max_time) max_time=temp;
+    if (temp<min_time) min_time=temp;
+    return 1;
+}
+
+int navl_done(void)
+{
+    navl_fini(g_reader->navl);
+    navl_close(g_reader->navl);
+    return 1;
+}
+
+void navl_results(int threadId)
+{
+    int idx;
+    int i;
+    uint64_t total_packets, total_bytes;
+    void* pShmEntry;
+
+
+    total_packets = 0;
+    total_bytes = 0;
+
+    //if (g_reader->option_dpi)
+    {
+        printf("\n NAVL DPI stats for CORE ID %d\n", threadId);
+        printf("\n AppProto    Packets  Class   Bytes        Cycles/Pkt      Cyclesnomem/Pkt  (min)  (max) ");
+        for(i=0;i<MAX_BIN;i++)
+            printf("<%s ",binStr[i]);
+        printf("\n ----------------------------------------------------------------------------------------------------------------------------------------------------\n");
+    }
+
+    //for (idx = 0; idx < g_reader->config_num_proto; idx++)
+    for (idx = 0; idx < pNavlCfg->num_protocols; idx++)
+    {
+        //if (g_reader->option_dpi)
+        {
+            if (g_reader->stats_pkt[threadId -1][idx].packets)
+            {
+                /* We need to provide protocol definitions */  
+                printf(" %-12s%-12" PRIu64 " %" PRIu64 " %" PRIu64 "      %" PRIu64 "       %" PRIu64 "    %ld    %ld .. " , 
+                        g_reader->stats_pkt[threadId -1][idx].name,
+                        g_reader->stats_pkt[threadId -1][idx].packets, 
+                        g_reader->stats_pkt[threadId -1][idx].class, 
+                        g_reader->stats_pkt[threadId -1][idx].bytes,
+                        g_reader->stats_pkt[threadId -1][idx].cycles/g_reader->stats_pkt[threadId -1][idx].packets, 
+                        g_reader->stats_pkt[threadId -1][idx].cycles_nomem/g_reader->stats_pkt[threadId -1][idx].packets,
+                        g_reader->stats_pkt[threadId -1][idx].cycles_nomem_min,
+                        g_reader->stats_pkt[threadId -1][idx].cycles_nomem_max);
+                for(i=0;i<MAX_BIN;i++) printf("%ld ",g_reader->stats_pkt[threadId -1][idx].bin_cycles[i]);
+                printf("\n");
+            }
+        }
+
+        total_packets += g_reader->stats_pkt[threadId -1][idx].packets;
+        total_bytes += g_reader->stats_pkt[threadId -1][idx].bytes;
+    }
+
+    if (!total_packets)
+        printf("\n No packets captured.\n");
+    else
+        printf("\n %" PRIu64 " packets captured (%" PRIu64 " bytes)\n", total_packets, total_bytes);
+
+    if (g_reader->stats_conns)
+        printf(" %" PRIu64 " connections tracked\n", g_reader->stats_conns);
+
+    printf("\n");
+    if (g_reader->option_track_memory)
+        navl_wrapper_mem_stat_print();
+
+    if (g_reader->alloc_curr != 0)
+        printf("Bytes not freed: %" PRIi64 "\n", g_reader->alloc_curr);
+
+    if (g_reader->alloc_peak != 0)
+           printf("Peak allocated: %" PRIi64 "\n", g_reader->alloc_peak);
+
+    printf("attr test: last http utl= %s\n",last_url);
+
+}
+
+static void 
+navl_wrapper_mem_stat_print()
+{
+    int i, j;
+    navl_wrapper_stat_t *stat;
+    char *name;
+
+    printf("                                          Curr      Peak      Fail   \n");
+    printf("-----------------------------------------------------------------------");
+
+    for (i = 0; i < g_reader->config_num_memctx; i++)
+    {
+        stat = &g_reader->stats_mem[i][0];
+        if (stat->peak == 0)
+        continue;
+
+        printf("\n\t%s\n", g_reader->ctx_name[i]);
+
+        for (j = g_reader->config_num_memobj - 1; j >= 0; j--)
+        {
+            navl_wrapper_stat_t *stat = &g_reader->stats_mem[i][j];
+            if (stat->peak == 0)
+            continue;
+
+            name = j ? g_reader->obj_name[j] : (char *)"other";
+
+            if (stat->peak || stat->fail)
+            printf("\t\t%-20s%10" PRIu64 "%10" PRIu64 "%10" PRIu64 "\n", name, stat->curr, stat->peak, stat->fail);
+        }
+    }
+    printf("\n\n");
+}
+
+/* Private memory stamp type for tracking memory with navl_wrapper_malloc/free */
+typedef struct
+{
+    size_t      size;       /* size of allocation */
+    short       ctx_tag;    /* ctx axis */
+    short       obj_tag;    /* obj axis */
+    char        mem[0];
+} memstamp_t;
+
+static void *navl_wrapper_malloc(size_t size)
+{
+    navl_handle_t handle;
+    navl_wrapper_stat_t *stat_mem;
+    int tag;
+    int ctx_tag, obj_tag;
+    unsigned long t1;
+    unsigned long t2;
+    malloc_inst+=1;
+    malloc_bytes+=size;
+    t1=netapi_timing_start();
+
+    assert(size);
+
+    /* In this context, the handle should be read using navl_handle_get() since
+     * the application cached handle (in this case g_reader->navl) will not be set
+     * until navl_open() returns. For this simple test we just assert that the handle
+     * is infact valid. */
+    handle = navl_handle_get();
+    assert(handle != 0);
+
+    /* Fetch the tags associated with this allocation. They will be used below to record
+     * statistics about allocations within the library on 2 axis. The upper 16 bits contain
+     * a memory obj tag and the lower 16 bits contain the allocation context tag. These
+     * tags are indices, the upper of which is available through navl_memory_ctx_num()
+     * and navl_memory_obj_num() resp. They are generated dynamically and may differ  between
+     * configurations. These total number of indices are available ONLY AFTER navl_open() 
+     * returns.
+     */
+    tag = navl_memory_tag_get(handle);
+    obj_tag = (tag >> 16);
+    ctx_tag = (tag & 0x0000FFFF);
+
+    /* You could do something better here and reallocate the matrix */
+    if (ctx_tag >= g_reader->config_num_memctx || obj_tag >= g_reader->config_num_memobj)
+    {
+        assert(0);
+        return NULL;
+    }
+
+    stat_mem = &g_reader->stats_mem[ctx_tag][obj_tag];
+
+    /* check limits */
+    if (!g_reader->option_limit_memory || (g_reader->alloc_curr + size < g_reader->option_limit_memory))
+    {
+        memstamp_t *ptr = (memstamp_t *)malloc(size + sizeof(memstamp_t));
+        if (ptr)
+        {
+            /* track peak values */
+            if ((g_reader->alloc_curr += size) > g_reader->alloc_peak)
+            g_reader->alloc_peak = g_reader->alloc_curr;
+
+            if ((stat_mem->curr += size) > stat_mem->peak)
+            stat_mem->peak = stat_mem->curr;
+
+            ptr->size = size;
+            ptr->ctx_tag = ctx_tag;
+            ptr->obj_tag = obj_tag;
+            t2=netapi_timing_start();
+            malloc_cycles += (unsigned long long)  (t2-t1);
+            return ptr->mem;
+        }
+    }
+    stat_mem->fail += size;
+    return NULL;
+}
+
+static void 
+navl_wrapper_free(void *p)
+{
+    unsigned long t1;
+    unsigned long t2;
+    free_inst += 1;
+    t1=netapi_timing_start();
+    if (!p)
+        return;
+
+    memstamp_t *ptr = (memstamp_t *)((char *)p - offsetof(memstamp_t, mem));
+    navl_wrapper_stat_t *stat_mem = &g_reader->stats_mem[ptr->ctx_tag][ptr->obj_tag];
+
+    assert(p == ptr->mem);
+
+    stat_mem->curr -= ptr->size;
+    g_reader->alloc_curr -= ptr->size;
+
+    free(ptr);
+    t2=netapi_timing_start();
+    free_cycles += (unsigned long long)  (t2-t1);
+}
+
+static int
+navl_wrapper_log_message(const char *level, const char *func, const char *format, ... )
+{
+    int res = 0;
+    char buf[4096];
+    va_list va;
+    va_start(va, format);
+
+    res = snprintf(buf, 4096, "%s: %s: ", level, func);
+    res += vsnprintf(buf + res, 4096 - res, format, va);
+    printf("%s\n", buf);
+    va_end(va);
+    return res;
+}
+
+//clear stats
+void clear_pkt_stats()
+{
+    int ret;
+    int threadId =Osal_nwalGetProcId();
+     memset(g_reader->stats_pkt, 0, sizeof(*g_reader->stats_pkt) * (g_reader->config_num_proto)*2);
+    /* now fetch all the protocol name ahead of time do we don't have to lookup them up on each packet */
+    for (ret = 0; ret != g_reader->config_num_proto; ret++)
+    {
+        navl_proto_get_name(g_reader->navl, ret, g_reader->stats_pkt[threadId -1][ret].name, sizeof(g_reader->stats_pkt[threadId -1][ret].name));
+        g_reader->stats_pkt[threadId -1][ret].cycles_nomem_min=10000000;
+    }
+}
diff --git a/ti/runtime/netapi/demo/src/navl_wrapper.h b/ti/runtime/netapi/demo/src/navl_wrapper.h
new file mode 100755 (executable)
index 0000000..113d8be
--- /dev/null
@@ -0,0 +1,161 @@
+/******************************************************************************
+ * FILE PURPOSE:  User space access to transport resources on SOC
+ ******************************************************************************
+ * FILE NAME:   navl_wrapper.h
+ *
+ * DESCRIPTION: NAVL Wrapper definitions and data structures
+ *
+ * REVISION HISTORY:
+ *
+ *  Copyright (c) Texas Instruments Incorporated 2014
+ *
+ *  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.
+ *
+ */
+/* ============================================================= */
+/**
+ *   @file  netapi.h
+ *
+ *   path  ti/runtime/netapi/demo/src/navl_wrapper.h
+ *
+ *   @brief  
+ *
+ */
+
+
+
+#ifndef __NAVL_WRAPPER_H
+#define __NAVL_WRAPPER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <navl/navl.h>
+
+#define NUM_PROCS 3
+
+#define NUM_FP_PROCS 2
+
+
+#define MAX_BIN 10
+typedef struct 
+{
+    uint32_t num_threads;
+    uint32_t num_protocols;
+} navl_wrapper_cfg_info_t;
+
+/* for tracking packet stats */
+typedef struct
+{
+    uint64_t packets;
+    uint64_t bytes;
+    char name[9];
+    uint64_t cycles;
+    uint64_t cycles_nomem;
+    long cycles_nomem_max;
+    long cycles_nomem_min;
+    uint64_t class; //# packets classified
+    long bin_cycles[MAX_BIN];
+    uint32_t pad[3];
+} navl_wrapper_pkt_stat_t;
+
+
+
+/* for tracking packets per thread/core basis */
+typedef struct 
+{
+    navl_wrapper_cfg_info_t     navl_cfg;
+    navl_wrapper_pkt_stat_t     stats_pkt[2];
+} navl_wrapper_shm_pkt_stats_t;
+
+
+
+
+/* for tracking memory stats */
+typedef struct
+{
+    int64_t curr;
+    int64_t peak;
+    int64_t fail;
+} navl_wrapper_stat_t;
+
+
+
+
+/* instance variables */
+typedef struct {
+/* handles */
+    navl_handle_t           navl;
+
+    /* configuration */
+    const char             *config_capfile;
+    const char             *config_plugins;
+    int                     config_num_proto;
+    int                     config_conn_id_attr;
+    int                     config_http_attr;
+    int                     config_num_memctx;
+    int                     config_num_memobj;
+
+    /* options */
+    int                     option_dpi;
+    int                     option_simple;
+    int                     option_track_memory;
+    int                     option_limit_memory;
+    int                     option_tunnel;
+    int                     option_realtime_mode;
+    int                     option_verbose;
+
+    /* diagnostics */
+    int                     error_navl;
+
+    /* statistics */
+#define NUM_MEM_CTX 50
+#define NUM_MEM_OBJ 50
+    navl_wrapper_stat_t    stats_mem[NUM_MEM_CTX][NUM_MEM_OBJ];
+    char                    ctx_name[NUM_MEM_CTX][64];
+    char                    obj_name[NUM_MEM_OBJ][64];
+    navl_wrapper_pkt_stat_t *stats_pkt[2];
+    uint64_t                stats_conns;
+
+    /* misc vars */
+    int                     running;
+    int64_t                 alloc_curr;
+    int64_t                 alloc_peak;
+} navl_mcb_t;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ti/runtime/netapi/demo/src/netapi_dpi_demo.c b/ti/runtime/netapi/demo/src/netapi_dpi_demo.c
new file mode 100755 (executable)
index 0000000..b074eb7
--- /dev/null
@@ -0,0 +1,1072 @@
+/******************************************\r
+ * File: nt_bench.c   \r
+ * Purpose:  benchmarks for NT.\r
+ **************************************************************\r
+ * FILE:  nt_bench.c\r
+ * \r
+ * DESCRIPTION:  netapi user space transport\r
+ *               library  test application : benchmarks\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 <stdio.h>\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+#include <string.h>\r
+#include <signal.h>\r
+#include <pthread.h>\r
+#include <sched.h>\r
+\r
+//#include "trie.h"\r
+#include <ti/runtime/netapi/netapi.h>\r
+#include <ti/runtime/hplib/hplib.h>\r
+#include "ti/runtime/netapi/pktio.h"\r
+#include "netapi_dpi_demo.h"\r
+#include "navl_wrapper.h"\r
+//#include "ti/runtime/netapi/test/net_test.h"\r
+#include <ti/drv/sa/salld.h>\r
+\r
+#include <ti/drv/qmss/device/k2e/src/qmss_device.c>\r
+#include <ti/drv/cppi/device/k2e/src/cppi_device.c>\r
+\r
+extern Rm_ServiceHandle   *rmClientServiceHandle;\r
+\r
+\r
+#define netapi_timing_start hplib_mUtilGetPmuCCNT\r
+\r
+\r
+extern NETCP_CFG_EXCEPTION_PKT_T expPkt_appid;\r
+\r
+STATS_T stats;\r
+paSysStats_t netcp_stats;\r
+struct dpi_stats dpis;\r
+\r
+#define VDPI\r
+#ifdef VDPI\r
+static int DPI=0;  //1 to enable\r
+static int DUMP_DPI_CONN=0;\r
+#endif\r
+\r
+static int scnt=0;\r
+volatile static int QUIT=0;\r
+static int XMIT=0;\r
+static int CAP=0;\r
+volatile int RESET=0; //to reset stats\r
+static int NTH=1;\r
+volatile static int PKTGEN=0;\r
+int pkt_len=64;\r
+\r
+\r
+\r
+NETCP_CFG_MACIF_T mac[NUM_PROCS];\r
+NETCP_CFG_MACIF_T mac0;\r
+NETCP_CFG_MACIF_T mac1;\r
+\r
+hplib_spinLock_T dpi_demo_thread_lock;\r
+\r
+\r
+static char usage[] = "usage: %s -s \n";\r
+\r
+\r
+\r
+\r
+//int procs =2; \r
+\r
+#define HPLIB_THREADID 0  // for main: HPLIB THREAD INSTANCE\r
+//__thread int our_core;\r
+static unsigned char dummy_mac[]={0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00};\r
+\r
+void house(NETAPI_SCHED_HANDLE_T *s);\r
+void our_stats_cb_mt(NETAPI_T h, paSysStats_t* pPaStats);\r
+void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);\r
+\r
+//sig handler\r
+void netTest_utilMySig(int x)\r
+{\r
+  QUIT=1;\r
+  scnt+=1;\r
+  printf(">net_test_dpi: recv'd signal %d cnt=%d\n",x,scnt);\r
+  if (scnt > 10) {printf(">dpi-demo: WARNING EXITING WITH PROPER SHUTDOWN LUTS LEFT ACTIVE\n");exit(1);}\r
+\r
+}\r
+\r
+\r
+void recv_cb_bridge(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],\r
+                         PKTIO_METADATA_T meta[], int n_pkts,\r
+                         uint64_t ts );\r
+\r
+\r
+/*************debug********************/\r
+void netTest_utilDumpDescr(unsigned long *p, int n)\r
+{\r
+   printf("--------dump of descriptor %d %x\n", n, (int) p);\r
+   printf("> %x %x %x %x %x %x %x %x\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]);\r
+   printf("> %x %x %x %x %x %x %x %x\n",p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);\r
+   printf("-----------------------------\n");\r
+}\r
+void netTest_utilDumpHeader(unsigned long *p, int n, int a, int r)\r
+{\r
+   printf("--------dump of header %d %x appID=%x flag1=%x\n", n, (int) p,a,r);\r
+   printf("> %0x %0x %0x %0x %0x %0x %0x %0x\n",\r
+          ntohl(p[0]),ntohl(p[1]),ntohl(p[2]),ntohl(p[3]),\r
+          ntohl(p[4]),ntohl(p[5]),ntohl(p[6]),ntohl(p[7]) );\r
+#if 0\r
+   printf("> %x %x %x %x %x %x %x %x\n",p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);\r
+   printf("> %x %x %x %x %x %x %x %x\n",p[16],p[17],p[18],p[19],p[20],p[21],p[22],p[23]);\r
+   printf("> %x %x %x %x %x %x %x %x\n",p[24],p[25],p[26],p[27],p[28],p[29],p[30],p[31]);\r
+#endif\r
+   printf("-----------------------------\n");\r
+}\r
+/*****************************************/\r
+\r
+void house(NETAPI_SCHED_HANDLE_T * s)\r
+{\r
+    int err;\r
+    NETAPI_SCHED_SHUTDOWN_T sched_shutdown;\r
+    int coreid;  //who we are\r
+    NETAPI_T nh= netapi_schedGetHandle(s);\r
+    coreid=(int) netapi_getCookie(nh);\r
+    \r
+    if (QUIT)\r
+    {\r
+        sched_shutdown.shutdown_type = NETAPI_SCHED_SHUTDOWN_NOW;\r
+        netapi_schedClose(s,&sched_shutdown,&err); \r
+        return;\r
+    }\r
+\r
+\r
+#ifdef VDPI\r
+    if (DUMP_DPI_CONN )\r
+        navl_dump_conn_info();\r
+#endif\r
+\r
+\r
+    /* only slow path threads get netcp stats, this needs to be set in cookie\r
+       during slow path thread creation*/\r
+    if (coreid & SP_THREAD_MASK)\r
+    {\r
+        netapi_netcpCfgReqStats(nh, our_stats_cb_mt, 0,&err);\r
+    }\r
+\r
+}\r
+\r
+unsigned long long CALIB=0;\r
+unsigned long long calibrate_idle(void)\r
+{\r
+    volatile unsigned long long  at1;\r
+    volatile unsigned long long  at2;\r
+    volatile unsigned long pt1;\r
+    volatile unsigned long pt2;\r
+    unsigned long long calib;\r
+    at1 = hplib_mUtilGetTimestamp();\r
+    pt1=netapi_timing_start();\r
+    for(;;)\r
+    {\r
+       pt2=netapi_timing_start()   ;\r
+       if ((pt2-pt1) >= 100000) break;\r
+    }\r
+    at2 = hplib_mUtilGetTimestamp();\r
+    \r
+    calib = ((unsigned long long) (pt2-pt1))/(at2-at1);\r
+    printf("calibrate:   arm time=%lld  -> arm cycles=%d calib=%lld\n", at2-at1, pt2-pt1, calib);\r
+    \r
+    return calib;\r
+}\r
+\r
+/*******************************************\r
+ *************NETAPI OBJECTS***************\r
+ *****************************************/\r
+static NETAPI_CFG_T our_netapi_default_cfg=\r
+{\r
+TUNE_NETAPI_PERM_MEM_SZ,\r
+128,  //start of packet offset for hw to place data on rx for default flow\r
+TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system\r
+TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use\r
+TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap\r
+64, //#descriptors w/o buffers in default heap\r
+TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap\r
+128,       //tail room\r
+256,      //extra room\r
+0,\r
+NULL\r
+};\r
+\r
+Pktlib_HeapHandle OurHeap;     //default heap, used by producer\r
+PKTIO_HANDLE_T * netcp_rx_chan;\r
+PKTIO_HANDLE_T * netcp_rx_chan2;\r
+PKTIO_HANDLE_T * netcp_tx_chan;\r
+\r
+PKTIO_CFG_T our_chan_cfg={PKTIO_RX_TX, PKTIO_LOCAL, PKTIO_Q_ANY, 8};\r
+PKTIO_CFG_T netcp_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};\r
+PKTIO_CFG_T netcp_rx_cfg2={PKTIO_RX, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8};\r
+PKTIO_CFG_T netcp_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};\r
+NETAPI_T netapi_handle;\r
+NETAPI_SCHED_HANDLE_T * our_sched;\r
+NETAPI_SCHED_HANDLE_T * scheduler[TUNE_NETAPI_NUM_CORES];\r
+NETAPI_SCHED_CONFIG_T our_sched_cfg={\r
+  NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000  //every 5000000 poll loops\r
+};\r
+\r
+NETCP_CFG_IP_T ip_rule0;\r
+NETCP_CFG_IP_T ip_rule1;\r
+\r
+\r
+PKTIO_CFG_T direct_to_cpsw_cfg={PKTIO_TX, PKTIO_GLOBAL, 648, 8};\r
+PKTIO_HANDLE_T * cpsw_tx_chan;\r
+\r
+PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};\r
+PKTIO_CONTROL_T poll_cannel_control={PKTIO_SET_POLL_FLAGS, NULL, nwal_POLL_DEFAULT_GLOB_PKT_Q};\r
+\r
+//template for fast path\r
+nwalTxPktInfo_t txPktInfoNoCrypto =\r
+{\r
+    NULL,                                                                                               /* p_pkt */\r
+    NWAL_TX_FLAG1_META_DATA_VALID,      /* txFlags */\r
+    0,                                                                                                  /* lpbackPass */\r
+    0,                                                                                                  /* enetport */\r
+    0,                                                                                                  /* msuSize */\r
+    0,                                                                                                   /* startOffset */\r
+    0,                                                    /* saOffBytes */\r
+    0,                                                                                                  /* saPayLoadLen */\r
+    0               ,                                                                                    /* saAhIcvOffBytes */\r
+    0,                                                                                                 /* saAhMacSize */\r
+    0,                                              /* etherLenOffBytes */\r
+    MAC_HEADER_LEN,         /* ipOffBytes */\r
+    MAC_HEADER_LEN + IP_HEADER_LEN,                                        /* l4OffBytes */\r
+    UDP_HEADER_LEN,                                                             /* l4HdrLen */\r
+    0,                                                                         /* pseudoHdrChecksum */\r
+    0                                                                                                   /* pLoadLen */\r
+};\r
+\r
+\r
+NETCP_CFG_ROUTE_T  test_route=\r
+{\r
+0,\r
+NULL,\r
+NULL,\r
+0//* to be filled in\r
+};\r
+\r
+NETCP_CFG_FLOW_HANDLE_T kernelFlow22;\r
+NETCP_CFG_FLOW_HANDLE_T kernelFlow23;\r
+\r
+/*************************END NETAPI OBJECTS***********************/\r
+\r
+static unsigned char all_mac[]={0,0,0,0,0,0};\r
+nwalIpAddr_t all_ip={0,0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
+\r
+\r
+static unsigned char all_dest[]={0xff,0xff,0xff,0xff,0xff,0xff};\r
+\r
+\r
+\r
+\r
+static unsigned long last_header[32/sizeof(unsigned long)];\r
+static unsigned long last_desc[64/sizeof(unsigned long)];\r
+\r
+//stats\r
+#define MAX_CORE 4\r
+int pkt_rx[MAX_CORE]; \r
+int pkt_tx[MAX_CORE]; \r
+unsigned long long pkt_rx_cycles[MAX_CORE]={0L};\r
+unsigned long long pkt_tx_cycles[MAX_CORE]={0L};\r
+unsigned long long pkt_cb_cycles[MAX_CORE]={0L};\r
+unsigned long long idle_cycles[MAX_CORE]={0L};\r
+volatile unsigned long long start_time[MAX_CORE];\r
+unsigned long long end_time[MAX_CORE];\r
+unsigned long long pkt_stall[MAX_CORE]={0L};\r
+//*********************************\r
+// packet generator\r
+//*********************************\r
+void gen_pkts(int np, int out_port);\r
+\r
+/******************************************************\r
+ * stats callback\r
+ *******************************************************/\r
+void our_stats_cb_mt(NETAPI_T h, paSysStats_t* pPaStats)\r
+{\r
+  stats.n_stats_cb +=1;\r
+  if(pPaStats) memcpy(&netcp_stats,pPaStats, sizeof(paSysStats_t));\r
+}\r
+\r
+void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)\r
+{\r
+    uint32_t numFreeDataPackets;\r
+    uint32_t            numZeroBufferPackets;\r
+    uint32_t            numPacketsinGarbage;\r
+    Pktlib_HeapStats    pktLibHeapStats;\r
+    int i,j;\r
+    unsigned long long bcpp;\r
+    unsigned long long bcpp_noc;\r
+    unsigned long long bcpp_app;\r
+    unsigned long long bcpp_tx;\r
+    unsigned long long npL;\r
+    unsigned long long cyclesL;\r
+    unsigned long long ccyclesL; //cache cycles\r
+    unsigned long long tmp_npL[TUNE_NETAPI_NUM_CORES];\r
+    unsigned long long tmp_cyclesL[TUNE_NETAPI_NUM_CORES];\r
+    unsigned long long tmp_ccyclesL[TUNE_NETAPI_NUM_CORES]; //cache cycles\r
+    NETAPI_SA_STATS_T netapi_sa_stats;\r
+\r
+    printf(">*****stats @ %lld (#cbs%d) \n", hplib_mUtilGetTimestamp(),stats.n_stats_cb);\r
+    //printf("netcp_tx_handle check %x\n", netcp_tx_chan->back);\r
+    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  min_rx=%d min_tx=%d ip=%d\n",\r
+             stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new, \r
+             stats.n_class0_rx, stats.n_class1_rx, \r
+             stats.n_class2_rx, stats.sec_rx, stats.secp_rx, stats.sb_rx, stats.sb_tx, stats.n_auth_ok,\r
+             stats.sec_tx, stats.rx_min, stats.tx_min, stats.ip);\r
+    printf(">if rx stats:  %d %d %d\n",stats.if_rx[0],stats.if_rx[1],stats.if_rx[2]);\r
+\r
+\r
+    printf(">core rx stats:  %d %d %d\n",stats.core_rx[1],stats.core_rx[2],stats.core_rx[3]);\r
+\r
+\r
+    /* need to maintain number of fast path threads in some global context */\r
+    for (j= 1;j < NUM_PROCS;j++)\r
+    {\r
+        tmp_npL[j]=0LL; tmp_cyclesL[j]=0LL; tmp_ccyclesL[j]=0LL;\r
+        netapi_schedGetStats(scheduler[j],&tmp_npL[j],&tmp_cyclesL[j],&tmp_ccyclesL[j]);\r
+        npL += tmp_npL[j];\r
+        cyclesL += tmp_cyclesL[j];\r
+        ccyclesL += tmp_ccyclesL[j];\r
+    }\r
+\r
+    if (npL && stats.rx)\r
+    {\r
+        bcpp = cyclesL/npL; \r
+        bcpp_noc = (cyclesL-ccyclesL)/npL; \r
+        bcpp_app = (stats.app_cycles-stats.tx_cache_cycles)/stats.rx;\r
+    }\r
+    else {bcpp = bcpp_noc=bcpp_app=0L;}\r
+    if (stats.tx)\r
+    {\r
+        bcpp_tx = (stats.send_cycles-stats.tx_cache_cycles)/stats.tx;\r
+    }\r
+    else\r
+    {\r
+        bcpp_tx = 0L;\r
+    }\r
+    printf(">         ++ busy cycles pp=%lld (%lld wo cache ops) (app+tx= %lld) (tx= %lld) ++\n",\r
+         bcpp,bcpp_noc,bcpp_app, bcpp_tx);\r
+\r
+\r
+#ifdef VDPI\r
+    navl_return_stats(\r
+    &dpis.n_ops,\r
+    &dpis.n_class,\r
+    &dpis.min_time,\r
+    &dpis.max_time,\r
+    &dpis.tot,\r
+    &dpis.m_op,\r
+    &dpis.m_bytes,\r
+    &dpis.n_err,\r
+    &dpis.f_op,\r
+    &dpis.m_cycles,\r
+    &dpis.f_cycles);\r
+\r
+    printf("dpi stats:  nops=%d nclass=%d min cycle=%d max  cycle=%d ave cycle=%lld #mallocs=%d #mbytes=%d n_err=%d fops=%d mCycles=%d fCycles=%d\n",\r
+    dpis.n_ops,\r
+    dpis.n_class,\r
+    dpis.min_time,\r
+    dpis.max_time,\r
+    dpis.n_ops? dpis.tot/dpis.n_ops : 0,\r
+    dpis.m_op,\r
+    dpis.m_bytes,\r
+    dpis.n_err,\r
+    dpis.f_op, dpis.m_cycles, dpis.f_cycles);\r
+    navl_results(1);\r
+    navl_results(2);\r
+#endif\r
+    if(pPaStats)\r
+    {\r
+        printf("C1 number of packets:           %d\n", pPaStats->classify1.nPackets);\r
+        printf("C1 number IPv4 packets:         %d\n", pPaStats->classify1.nIpv4Packets);\r
+        printf("C1 number IPv6 packets:        %d\n", pPaStats->classify1.nIpv6Packets);\r
+        printf("C1 number Custom packets:        %d\n", pPaStats->classify1.nCustomPackets);\r
+        printf("C1 number SRIO packets:        %d\n", pPaStats->classify1.nSrioPackets);\r
+        printf("C1 number LLC/SNAP Fail packets:        %d\n", pPaStats->classify1.nLlcSnapFail);\r
+        printf("C1 number table matched:        %d\n", pPaStats->classify1.nTableMatch);\r
+        printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);\r
+        printf("C1 number IP Fragmented packets: %d\n", pPaStats->classify1.nIpFrag);\r
+        printf("C1 number IP Depth Overflow: %d\n", pPaStats->classify1.nIpDepthOverflow);\r
+        printf("C1 number VLAN Depth Overflow: %d\n", pPaStats->classify1.nVlanDepthOverflow);\r
+        printf("C1 number GRE Depth Overflow: %d\n", pPaStats->classify1.nGreDepthOverflow);\r
+        printf("C1 number MPLS Packets: %d\n", pPaStats->classify1.nMplsPackets);\r
+        printf ("C1 number of parse fail:        %d\n",pPaStats->classify1.nParseFail);\r
+        printf("C1 number of Invalid IPv6 Opt:  %d\n", pPaStats->classify1.nInvalidIPv6Opt);\r
+        printf("C1 number of TX IP Fragments:  %d\n", pPaStats->classify1.nTxIpFrag);\r
+        printf ("C1 number of silent discard:    %d\n",pPaStats->classify1.nSilentDiscard);\r
+        printf("C1 number of invalid control:   %d\n", pPaStats->classify1.nInvalidControl);\r
+        printf ("C1 number of invalid states:    %d\n",pPaStats->classify1.nInvalidState);\r
+        printf ("C1 number of system fails:      %d\n",pPaStats->classify1.nSystemFail);\r
+        printf ("C2 number Packets  :           %d\n",pPaStats->classify2.nPackets);\r
+        printf ("C2 number udp           :      %d\n",pPaStats->classify2.nUdp);\r
+        printf ("C2 number tcp           :      %d\n",pPaStats->classify2.nTcp);\r
+        printf ("C2 number Custom       :      %d\n",pPaStats->classify2.nCustom);\r
+        printf ("C2 number silent drop   :      %d\n",pPaStats->classify2.nSilentDiscard);\r
+        printf ("C2 number invalid cntrl :      %d\n\n",pPaStats->classify2.nInvalidControl);\r
+        printf ("C2 number Modify Stats Cmd Fail :      %d\n\n",pPaStats->modify.nCommandFail);\r
+    }\r
+    Pktlib_getHeapStats(OurHeap, &pktLibHeapStats);\r
+\r
+    printf("main heap stats>  #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,\r
+                                pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);\r
+    printf("               >  #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n", \r
+                        pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,\r
+                        pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);\r
+}\r
+\r
+NETAPI_T worker_nh[MAX_NUM_CORES];\r
+\r
+void slow_path_thread(uint32_t index)\r
+{\r
+    int err, i;;\r
+    uint32_t thread_num;\r
+    cpu_set_t cpu_set;\r
+\r
+    /* index being passed in is the core we want to run the thread on */\r
+    thread_num = index;\r
+    printf("slow_path_thread, mypid: %d, core_id %d\n", gettid(), thread_num);\r
+\r
+    CPU_ZERO( &cpu_set);\r
+    for (i = 0; i < 1;i++)\r
+    {\r
+        CPU_SET( i, &cpu_set);\r
+    }\r
+    hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);\r
+    worker_nh[thread_num] = netapi_init(NETAPI_CORE_MASTER,NULL);\r
+\r
+    if (worker_nh[thread_num] == NULL)\r
+    {\r
+        printf("slow_path_thread: netapi_init failure, exiting\n");\r
+        exit(1);\r
+    }\r
+    netapi_setCookie(worker_nh[thread_num],(void*)(thread_num | SP_THREAD_MASK));\r
+\r
+    scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],&our_sched_cfg, &err);\r
+    if (!scheduler[thread_num]) \r
+    {\r
+        printf("sched create failed for core%d\n",thread_num);\r
+        goto ERR_slow_path_thread;\r
+    }\r
+    scheduler[thread_num]->config.yield = TRUE;\r
+    scheduler[thread_num]->config.pollGarbageQ = TRUE;\r
+    scheduler[thread_num]->config.pollCtrlQ = TRUE;\r
+    printf("Slow Path thread: %d setup complete, running on ARM CORE: %d\n",\r
+    index,index);\r
+\r
+\r
+    netapi_schedRun(scheduler[thread_num], &err);\r
+\r
+ERR_slow_path_thread:\r
+    printf("slow_path_thread: calling netapi_shutdown\n");\r
+    netapi_shutdown(worker_nh[thread_num]);\r
+}\r
+\r
+\r
+void fast_path_thread(uint32_t index)\r
+{\r
+    int err, i;\r
+    PKTIO_HANDLE_T *rx_chan;\r
+    PKTIO_HANDLE_T *sb_rx_chan;\r
+    uint32_t thread_num;\r
+    int navlHandle;\r
+\r
+\r
+    cpu_set_t cpu_set;\r
+\r
+    CPU_ZERO( &cpu_set);\r
+    thread_num = index;\r
+    printf("fast_path_thread: core %d\n", index);\r
+\r
+\r
+    CPU_SET( thread_num, &cpu_set);\r
+    hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);\r
+\r
+\r
+    hplib_mSpinLockLock(&dpi_demo_thread_lock);\r
+    worker_nh[thread_num]=netapi_init(NETAPI_CORE_MASTER,NULL);\r
+    \r
+    if (worker_nh[thread_num] == NULL)\r
+    {\r
+        printf("fast_path_thread: netapi_init failure, exiting\n");\r
+        hplib_mSpinLockUnlock(&dpi_demo_thread_lock);\r
+        exit(1);\r
+    }\r
+    else\r
+    {\r
+#ifdef VDPI\r
+            navlHandle = navl_per_thread_init(thread_num);\r
+#endif\r
+    }\r
+    hplib_mSpinLockUnlock(&dpi_demo_thread_lock);\r
+\r
+\r
+    if (worker_nh[thread_num] == NULL)\r
+    {\r
+        printf("fast_path_thread: netapi_init failure, exiting\n");\r
+        exit(1);\r
+    }\r
+    \r
+    /* open netcp default RX channels*/\r
+    rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_RX, (PKTIO_CB) recv_cb_bridge, &netcp_rx_cfg,  &err);\r
+\r
+\r
+    netapi_setCookie(worker_nh[thread_num],(void*)thread_num);\r
+    \r
+    scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],\r
+                                            &our_sched_cfg,\r
+                                            &err);\r
+    if (!scheduler[thread_num]) \r
+        {\r
+        printf("sched create failed for core%d\n",thread_num);\r
+        goto ERR_fast_path_thread;\r
+        //exit(1);\r
+    }\r
+\r
\r
+    scheduler[thread_num]->config.yield = FALSE;\r
+    scheduler[thread_num]->config.pollGarbageQ = FALSE;\r
+    scheduler[thread_num]->config.pollCtrlQ = FALSE;\r
+   /* Entry point to scheduler */\r
+\r
+\r
+    printf("Fast Path thread: %d setup complete, running on ARM CORE: %d\n",\r
+    index,index);\r
+    netapi_schedRun(scheduler[thread_num], &err);\r
+\r
+ERR_fast_path_thread:\r
+#ifdef VDPI\r
+        navl_fini(navlHandle);\r
+#endif\r
+    netapi_pktioClose(rx_chan, &err);\r
+\r
+    printf("fast_path_thread: calling netapi_shutdown\n");\r
+    netapi_shutdown(worker_nh[thread_num]);\r
+}\r
+\r
+\r
+//******************************\r
+//  main program\r
+//*****************************\r
+int main(int argc, char **argv)\r
+{\r
+    int err,i;\r
+    int j;\r
+    int32_t             errCode;\r
+    Pktlib_HeapIfTable*  pPktifTable;\r
+    Pktlib_HeapCfg heapCfg;\r
+    long t1, t2 ;\r
+    cpu_set_t cpu_set;\r
+    int c;\r
+    int statsQueryRequest = 0;\r
+\r
+#if 0\r
+    if (initRm())\r
+    {\r
+        printf("main: initRm() returned error\n");\r
+        exit(1);\r
+    }\r
+#endif\r
+\r
+\r
+#if 1\r
+\r
+    if (argc == 2)\r
+    {\r
+        printf("main: argument %s\n", argv[1]);\r
+        if(!(strcmp(argv[1], "stats")))\r
+        {\r
+            statsQueryRequest =1;\r
+            printf("querying for stats\n");\r
+        }\r
+    }\r
+    printf("statsQueryReqeust: %d\n", statsQueryRequest);\r
+\r
+\r
+#endif\r
+\r
+#if 1\r
+    if (statsQueryRequest)\r
+    {\r
+        navl_wrapper_cfg_info_t *pNavlCfg;\r
+        navl_wrapper_pkt_stat_t *pStats1;\r
+        navl_wrapper_pkt_stat_t *pStats2;\r
+        void* pTemp;\r
+        \r
+        void* pShmBase = hplib_shmOpen();\r
+        if (pShmBase)\r
+        {\r
+            pTemp = hplib_shmGetEntry(pShmBase, APP_ENTRY_1);\r
+            pNavlCfg =  (navl_wrapper_cfg_info_t*)pTemp;\r
+\r
+            pStats1 = pTemp + sizeof(navl_wrapper_cfg_info_t);\r
+\r
+        \r
+            pStats2 = pTemp + sizeof(navl_wrapper_cfg_info_t) +\r
+                    (sizeof(navl_wrapper_pkt_stat_t)*pNavlCfg->num_protocols);\r
+\r
+            printf("main: pStats1: 0x%x pStats2: 0x%x\n", pStats1, pStats2);\r
+        }\r
+        sleep(10);\r
+        exit(1);\r
+    }\r
+#endif\r
+    printf("***net_test_dpi.. worker threads running on %d cores\n",NUM_FP_PROCS);\r
+\r
+    signal(SIGINT,netTest_utilMySig);\r
+\r
+    CPU_ZERO( &cpu_set);\r
+    CPU_SET( 0, &cpu_set);\r
+    hplib_utilSetupThread(HPLIB_THREADID, &cpu_set, hplib_spinLock_Type_LOL);\r
+\r
+    /* create netapi */\r
+    our_netapi_default_cfg.rmHandle = rmClientServiceHandle;\r
+    netapi_handle = netapi_init(NETAPI_SYS_MASTER,\r
+                                &our_netapi_default_cfg);\r
+    if (netapi_handle == NULL)\r
+    {\r
+        printf("main: netapi_init failure, exiting\n");\r
+        exit(1);\r
+    }\r
+    netapi_netcpCfgExceptions(netapi_handle,\r
+                              NETCP_CFG_ALL_EXCEPTIONS,\r
+                              NETCP_CFG_ACTION_DISCARD,\r
+                              (NETCP_CFG_ROUTE_HANDLE_T)NULL);\r
+\r
+    /* open the main heap */\r
+    OurHeap = Pktlib_findHeapByName("netapi");\r
+    if (!OurHeap)\r
+    {\r
+        printf("findheapbyname fail\n");\r
+        exit(1);\r
+    }\r
+\r
+    //if we want to relay network packets, we create a handle to the \r
+    //default netcp receive queue here\r
+    netcp_rx_chan= netapi_pktioOpen(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb_bridge, &netcp_rx_cfg,  &err);\r
+    if (!netcp_rx_chan)\r
+    {\r
+        printf("pktio open RX failed err=%d\n",err);\r
+        exit(1);\r
+    }\r
+\r
+    netcp_tx_chan= netapi_pktioOpen(netapi_handle, NETCP_TX, (PKTIO_CB) NULL, &netcp_tx_cfg,  &err);\r
+    if (!netcp_tx_chan)\r
+    {\r
+        printf("pktio open TX failed err=%d\n",err);\r
+        exit(1);\r
+    }\r
+    else  //install a fast path template into the NETCP TX channel\r
+    {\r
+        PKTIO_CONTROL_T control2;\r
+        control2.op = PKTIO_UPDATE_FAST_PATH;\r
+        PKTIO_CFG_T cfg2;\r
+        memset(&cfg2, 0, sizeof(PKTIO_CFG_T));\r
+        cfg2.fast_path_cfg.fp_send_option = PKTIO_FP_NO_CRYPTO_NO_CKSUM_PORT;\r
+        cfg2.fast_path_cfg.txPktInfo= &txPktInfoNoCrypto;\r
+        netapi_pktioControl(netcp_tx_chan, NULL, &cfg2, &control2, &err);\r
+   }\r
+\r
+#ifdef VDPI\r
+    navl_setup();\r
+#endif\r
+    /*********************************************/\r
+    /*****************end NETAPI STARTUP**********/\r
+    /*********************************************/\r
+\r
+    //now creaate a simple netcp rule\r
+    //to get a lot of packets\r
+    mac0 = netapi_netcpCfgCreateMacInterface(\r
+                      netapi_handle,\r
+                      &all_mac[0],\r
+                      NULL,\r
+                      0,\r
+                      1,\r
+                      (NETCP_CFG_ROUTE_HANDLE_T)  NULL,\r
+                      (NETCP_CFG_VLAN_T ) NULL ,  //future\r
+                      0x0800,\r
+                      1,\r
+                      &err);\r
+    if (err) {printf("addmac0 failed %d\n",err); exit(1); }\r
+    else printf("addmac0 sucess\n");\r
+\r
+    mac1 = netapi_netcpCfgCreateMacInterface(\r
+                      netapi_handle,\r
+                      &all_mac[0],\r
+                      NULL,\r
+                      1,\r
+                      2,\r
+                      (NETCP_CFG_ROUTE_HANDLE_T)  NULL,\r
+                      (NETCP_CFG_VLAN_T ) NULL ,  //future\r
+                      0x0800,\r
+                      1,\r
+                      &err);\r
+    if (err) {printf("addmac1 failed %d\n",err); exit(1); }\r
+    else printf("addmac1 sucess\n");\r
+\r
+#if 0\r
+    ip_rule0=netapi_netcpCfgAddIp(\r
+                      netapi_handle,\r
+                      0,\r
+                      nwal_IPV4,\r
+                      &all_ip,\r
+                      NULL,  //all IP\r
+                      NULL,\r
+                      (NETCP_CFG_ROUTE_HANDLE_T) NULL,\r
+                      (void*)NULL,\r
+                      &err\r
+        );\r
+\r
+\r
+    ip_rule1=netapi_netcpCfgAddIp(\r
+                      netapi_handle,\r
+                      1,\r
+                      nwal_IPV4,\r
+                      &all_ip,\r
+                      NULL,  //all IP\r
+                      NULL,\r
+                      (NETCP_CFG_ROUTE_HANDLE_T) NULL,\r
+                      (void*)NULL,\r
+                      &err\r
+        );\r
+#endif\r
+    if (err) {printf("addip0 failed %d\n",err); exit(1); }\r
+\r
+\r
+\r
+\r
+    //calibrate idle\r
+    CALIB = calibrate_idle();\r
+\r
+    //**************************************\r
+    //Create a slow path thread\r
+    //***************************************\r
+    {\r
+    pthread_t *thrs;\r
+    int p;\r
+    char c;\r
+    thrs = malloc( sizeof( pthread_t ) * NUM_PROCS );\r
+    if (thrs == NULL)\r
+    {\r
+        perror( "malloc" );\r
+        return -1;\r
+    }\r
+    printf( "dpi-demo: Starting slow_path_thread on core 0\n");\r
+\r
+    if (pthread_create( &thrs[0], NULL, (void*)slow_path_thread,\r
+                      (void *)0 ))  //start at core 0\r
+    {\r
+        perror( "pthread_create" );\r
+        exit(1);\r
+    }\r
+\r
+\r
+    for (j= 1;j < NUM_PROCS;j++)\r
+    {\r
+        printf( "dpi-demo: Starting fast_path_thread on core 1\n");\r
+        if (pthread_create( &thrs[j], NULL, (void*)fast_path_thread,\r
+                      (void *)j ))  //start at core 1\r
+        {\r
+            perror( "pthread_create" );\r
+            exit(1);\r
+        }\r
+\r
+    }\r
+    //this thread of execution (main) now just waits on user input\r
+    for(;;)\r
+    {\r
+        printf(">");\r
+        c=getchar();\r
+        if (c=='C')\r
+        {\r
+            CAP=!CAP; \r
+            printf("CAPTURE= %d\n", CAP);\r
+        }\r
+        else if (c=='q') {QUIT=1;break;}\r
+        else if (c=='s')\r
+            our_stats_cb(netapi_handle, &netcp_stats);\r
+#ifdef VDPI\r
+           else if (c=='c') \r
+            {navl_clear_stats();printf("> Clearing DPI stats\n");}\r
+           else if (c=='v') navl_set_verbose();\r
+           else if (c=='p') \r
+             {DUMP_DPI_CONN = !DUMP_DPI_CONN;printf(">  **DPI CONN DUMP is %s ** \n", DUMP_DPI_CONN ?"enabled":"disabled");}\r
+           else if (c=='d') \r
+             {DPI = !DPI;printf(">  **DPI is %s ** \n", DPI?"enabled":"disabled");}\r
+#endif\r
+        else if (c=='!') {system("sh");}\r
+#if 0\r
+        else if (c=='t') {XMIT=!XMIT; printf("XMIT= %d\n", XMIT); }\r
+        else if (c=='p') {PKTGEN=!PKTGEN; printf("PKTGEN= %d @%d bytes\n",PKTGEN,pkt_len);}\r
+        else if (c=='S') {pkt_len+=64; if (pkt_len>1500) pkt_len=64; printf("pkt_len=%d\n",pkt_len);}\r
+        else if (c=='1')\r
+        {\r
+            RESET=1;\r
+        }\r
+        else if (c=='2')\r
+        {\r
+            RESET=(NUM_PROCS>=2) ?2:1;\r
+        }\r
+        else if (c=='3')\r
+        {\r
+            RESET=(NUM_PROCS>=3) ?3: 1;\r
+        }\r
+#endif\r
+        else if ((c=='h')||(c=='?'))\r
+        {\r
+            printf("> 'q' to quit,  's' for stats,'d' to dump capture\n,> 'h' for help\n ");\r
+        }\r
+#if 1\r
+        else if (c=='r')\r
+        {\r
+            netTest_utilDumpHeader(&last_header[0], 0,0,0);\r
+            netTest_utilDumpDescr(&last_desc[0], 0);\r
+        }\r
+        else if (c=='b')\r
+        {\r
+           int cc;\r
+            unsigned long long et= hplib_mUtilGetTimestamp();\r
+            for(cc=1;cc<NUM_PROCS+1;cc++)\r
+           printf(">NT_BENCH STATS core%d:    %d received   %d xmitted,  \n %lld idle cycles,  %lld duration ticks  idle=%lld\n pkt rate =%lld stall=%lld\n",\r
+                       cc,\r
+                       pkt_rx[cc],pkt_tx[cc],\r
+                       idle_cycles[cc],\r
+                       (et-start_time[cc]),\r
+                       (et>start_time[cc]) ? (idle_cycles[cc]*100)/(CALIB*(et-start_time[cc])): 0LL,\r
+                       (et>start_time[cc]) ? pkt_rx[cc]/(6LL*(et-start_time[cc])/1180000000LL): 0LL,\r
+                       pkt_stall[cc]\r
+                    );\r
+            }\r
+#endif\r
+    }\r
+\r
+#ifdef VDPI\r
+            navl_done();\r
+#endif\r
+\r
+        //wait for completion \r
+        printf("main task now pending on thread completion\n");\r
+        for (i = 0; i < NUM_PROCS; i++)\r
+                pthread_join( thrs[i], NULL );\r
+\r
+        free( thrs );\r
+    \r
+    }\r
+\r
+    /*************************************************\r
+     ************CLEAN UP****************************\r
+     ************************************************/\r
+    //get rid of rule, in the case that we are relaying packets\r
+    //also close our netcp rx channel\r
+    netapi_netcpCfgDelMac(netapi_handle,0,&err);\r
+    netapi_netcpCfgDelMac(netapi_handle,1,&err);\r
+    \r
+    netapi_pktioClose(netcp_rx_chan,&err);\r
+    netapi_pktioClose(netcp_tx_chan,&err);\r
+\r
+\r
+    //done\r
+    netapi_shutdown(netapi_handle);\r
+\r
+\r
+    //!finished!\r
+}\r
+#if 1\r
+static inline void send_it(Ti_Pkt *tip, int len, int out_port)\r
+{\r
+  int err=0;\r
+  PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};\r
+  nwalTxPktInfo_t meta_tx2={0};\r
+  int coreid=Osal_nwalGetProcId();\r
+  if (len<60)\r
+  {\r
+     unsigned int templen;\r
+     char * p_pkt;\r
+     len=60;\r
+     Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen\r
+     Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);\r
+  }\r
+  Pktlib_setPacketLen(tip,len);\r
+  meta_tx2.txFlag1 = NWAL_TX_FLAG1_META_DATA_VALID;\r
+  meta_tx2.ploadLen = len ;\r
+  meta_tx2.enetPort=out_port;\r
+  meta2.u.tx_meta=&meta_tx2;\r
+  stats.tx+=1;\r
+  if(coreid<MAX_NUM_CORES)\r
+    pkt_tx[coreid]+=1;\r
+  netapi_pktioSend(netcp_tx_chan,tip,&meta2,&err);\r
+}\r
+#endif\r
+void recv_cb_bridge(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],\r
+                         PKTIO_METADATA_T meta[], int n_pkts,\r
+                         uint64_t ts )\r
+{\r
+int i;\r
+int len;\r
+int p;\r
+Ti_Pkt * tip;\r
+unsigned int appid;\r
+unsigned int templen;\r
+char * p_pkt;\r
+unsigned long t1;\r
+unsigned long t2;\r
+unsigned long long ct1;\r
+unsigned long long ct2;\r
+unsigned short ip_pl;\r
+unsigned long long n_c_ops;\r
+int ifno;\r
+int out_port;\r
+\r
+int coreid=Osal_nwalGetProcId();\r
+\r
+\r
+pasahoLongInfo_t* protoInfo;\r
+\r
+t1=netapi_timing_start();\r
+ct1 =Osal_cache_op_measure(&n_c_ops);\r
+for(i=0;i<n_pkts;i++)\r
+{\r
+        \r
+        tip = p_recv[i];\r
+        appid = ((unsigned int)meta[i].u.rx_meta->appId)&0xff000000;\r
+        if (appid == NETAPI_NETCP_MATCH_GENERIC_IP) \r
+        {\r
+           stats.ip+=1;\r
+        }\r
+\r
+        protoInfo=nwal_mGetProtoInfo(tip);\r
+        ifno = nwal_mGetRxEmacPort( protoInfo);\r
+        if (ifno ==1) out_port=2; else out_port=1;\r
+        if(coreid<MAX_NUM_CORES) stats.core_rx[coreid]+=1;\r
+        if (ifno < MAX_NUM_INTERFACES) stats.if_rx[ifno]+=1;\r
+        Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen\r
+        if (CAP==coreid)\r
+        {\r
+            memcpy((unsigned char *)&last_header[0],p_pkt,32);\r
+            memcpy((unsigned char*)&last_desc[0],tip,64);\r
+        }\r
+        len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer\r
+        stats.rx+=1;\r
+        //printf("recv_cb_bridge: appId: 0x%x, out_port: %d\n", appid, out_port);\r
+        if (appid == NETAPI_NETCP_MATCH_GENERIC_MAC)\r
+        {\r
+#ifdef VDPI\r
+            {\r
+                if (DPI)\r
+                    navl_process_pkt(p_pkt, len);\r
+            }\r
+#endif\r
+        }\r
+\r
+    \r
+ //printf("recv_cb_bridge: coreId: %d, outPort %d\n", coreid, out_port);\r
+        //Pktlib_freePacket(tip);\r
+        send_it(tip,len+4,out_port);\r
+}\r
+t2=netapi_timing_start();\r
+ct2 =Osal_cache_op_measure(&n_c_ops);\r
+stats.app_cycles +=  (unsigned long long) (t2-t1);\r
+stats.tx_cache_cycles += (unsigned long long) (ct2-ct1);\r
+return;\r
+}\r
+\r
+#define NTOPOP 150\r
+volatile Ti_Pkt * pHd[NTOPOP];\r
+\r
+#define PKTGEN_PKT_LEN pkt_len\r
+#define MAXP 4   //max ports \r
+void gen_pkts(int np, int out_port)\r
+{\r
+    int i;\r
+    int p=0;\r
+    unsigned long * pI ;\r
+    Ti_Pkt * tip;\r
+    int len;\r
+    unsigned char * pData;\r
+    int cstall=0;\r
+    int coreid = Osal_nwalGetProcId();\r
+    for(i=0;i<np;)\r
+    {\r
+        //set out output port\r
+        if (out_port)\r
+        {\r
+            p=out_port;\r
+        }\r
+        else //flip flop\r
+        {\r
+            p+=1;\r
+            if(p>MAXP) p=1;\r
+        }\r
+        //get a packet\r
+        tip=Pktlib_allocPacket(OurHeap,PKTGEN_PKT_LEN);\r
+        pI = (unsigned long *) tip;\r
+        if (!tip)\r
+        {\r
+            pkt_stall[coreid]+=1;\r
+            cstall+=1;\r
+            if (cstall >= 100000) \r
+            {\r
+                printf("worker core %d, max stall hit,, exiting.\n",coreid); \r
+               return;\r
+           }\r
+            continue;\r
+        }\r
+        cstall=0;\r
+        Pktlib_getDataBuffer(tip,&pData,&len);\r
+        memcpy(pData,&dummy_mac,14);\r
+        Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, pData,PKTGEN_PKT_LEN);\r
+        Pktlib_setPacketLen(tip,PKTGEN_PKT_LEN);\r
+        pI[1]=0x80000000;\r
+        //pI[2] &= 0xfff0ffff ;move to pktio send function\r
+\r
+        //capture packet just in case\r
+        if (CAP==coreid)\r
+        {\r
+            unsigned int templen;\r
+            char * p_pkt;\r
+            Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen\r
+            memcpy((unsigned char *)&last_header[0],p_pkt,32);\r
+            memcpy((unsigned char*)&last_desc[0],tip,64);\r
+        }\r
+\r
+        //send  packet\r
+        send_it(tip, PKTGEN_PKT_LEN, p);\r
+        pkt_tx[coreid]+=1;\r
+        i+=1;\r
+   }\r
+\r
+    return;\r
+}\r
diff --git a/ti/runtime/netapi/demo/src/netapi_dpi_demo.h b/ti/runtime/netapi/demo/src/netapi_dpi_demo.h
new file mode 100755 (executable)
index 0000000..efdc094
--- /dev/null
@@ -0,0 +1,65 @@
+#include <stdlib.h>\r
+\r
+#define MAC_HEADER_LEN          14\r
+#define IP_HEADER_LEN           20\r
+#define UDP_HEADER_LEN          8\r
+\r
+#define MAX_NUM_INTERFACES 64\r
+#define MAX_NUM_CORES 4\r
+\r
+#define SP_THREAD_MASK 0xF0000000\r
+#define THREAD_NUM_MASK 0x000000FF\r
+\r
+\r
+typedef struct stats_t\r
+{\r
+    long itx;  //initially generated\r
+    long itx2;\r
+    long rx;\r
+    long tx;\r
+    long n_bad;\r
+    long n_new;\r
+    long n_class0_rx;   //count of pkts classified \r
+    long n_class1_rx;   //count of pkts classified \r
+    long n_class2_rx;   //count of pkts classified \r
+    long n_t1;\r
+    long n_t2;\r
+    long n_t3;\r
+    long sec_tx;\r
+    long sec_rx;\r
+    long sb_tx;\r
+    long sb_rx;\r
+    long secp_rx;\r
+    long n_auth_ok;\r
+    unsigned long long  app_cycles;\r
+    unsigned long long  send_cycles;\r
+    unsigned long long  tx_cache_cycles;\r
+    long rx_min;\r
+    long tx_min;\r
+    long if_rx[MAX_NUM_INTERFACES];\r
+    long  core_rx[MAX_NUM_CORES];\r
+    long  n_stats_cb;\r
+    long  ip;\r
+} STATS_T;\r
+\r
+typedef struct head_t\r
+{\r
+       long ip[5];\r
+       long udp[2];\r
+} HEAD_T;\r
+\r
+struct dpi_stats\r
+{\r
+unsigned long n_ops;\r
+unsigned long n_class;\r
+unsigned long min_time;\r
+unsigned long max_time;\r
+unsigned long long tot;\r
+unsigned long m_op;\r
+unsigned long m_bytes;\r
+unsigned long n_err;\r
+unsigned long f_op;\r
+unsigned long m_cycles;\r
+unsigned long f_cycles;\r
+};\r
+\r