summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4e33dbe)
raw | patch | inline | side by side (parent: 4e33dbe)
author | Tinku Mannan <tmannan@ti.com> | |
Tue, 5 Aug 2014 15:13:32 +0000 (11:13 -0400) | ||
committer | Tinku 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] | patch | blob |
ti/runtime/netapi/demo/src/Makefile | [new file with mode: 0755] | patch | blob |
ti/runtime/netapi/demo/src/navl_external_posix.c | [new file with mode: 0755] | patch | blob |
ti/runtime/netapi/demo/src/navl_wrapper.c | [new file with mode: 0755] | patch | blob |
ti/runtime/netapi/demo/src/navl_wrapper.h | [new file with mode: 0755] | patch | blob |
ti/runtime/netapi/demo/src/netapi_dpi_demo.c | [new file with mode: 0755] | patch | blob |
ti/runtime/netapi/demo/src/netapi_dpi_demo.h | [new file with mode: 0755] | patch | blob |
diff --git a/ti/runtime/netapi/demo/build/Makefile b/ti/runtime/netapi/demo/build/Makefile
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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