Message ID | 1406815270-13218-1-git-send-email-maxim.uvarov@linaro.org |
---|---|
State | New |
Headers | show |
On 31 July 2014 10:01, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> > --- > Hello, > > This is ODP Snort/DAQ module. The propose of this change is to publish it > on github as separate project. Sending to our mailing list for > review/testing. > > Anders, please check if we need something more odp specific to m4 scripts. > > I did compilation check and stress test blasting pcap to that module. > Can we migrate this test to LAVA ? > > Thank you, > Maxim. > > > LICENSE | 29 ++++ > Makefile.am | 8 + > README | 9 ++ > configure.ac | 43 +++++ > daq_odp.c | 394 > +++++++++++++++++++++++++++++++++++++++++++++ > m4/ax_cflags_gcc_option.m4 | 221 +++++++++++++++++++++++++ > m4/sf.m4 | 198 +++++++++++++++++++++++ > 7 files changed, 902 insertions(+) > create mode 100644 LICENSE > create mode 100644 Makefile.am > create mode 100644 README > create mode 100644 configure.ac > create mode 100644 daq_odp.c > create mode 100644 m4/ax_cflags_gcc_option.m4 > create mode 100644 m4/sf.m4 > > diff --git a/LICENSE b/LICENSE > new file mode 100644 > index 0000000..441ba51 > --- /dev/null > +++ b/LICENSE > @@ -0,0 +1,29 @@ > +Copyright (c) 2013-2014, Linaro Limited > +All rights reserved. > + > +SPDX-License-Identifier: BSD-3-Clause > + > +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 Linaro Limited 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 HOLDER 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. > diff --git a/Makefile.am b/Makefile.am > new file mode 100644 > index 0000000..93c5cdf > --- /dev/null > +++ b/Makefile.am > @@ -0,0 +1,8 @@ > +AUTOMAKE_OPTIONS = foreign > + > +ACLOCAL_AMFLAGS = -I m4 > + > +pkglib_LTLIBRARIES = daq_odp.la > +daq_example_la_SOURCES = daq_odp.c > +daq_example_la_CFLAGS = -DBUILDING_SO > +daq_example_la_LDFLAGS = -module -export-dynamic -avoid-version -shared > diff --git a/README b/README > new file mode 100644 > index 0000000..eec4f87 > --- /dev/null > +++ b/README > @@ -0,0 +1,9 @@ > +OpenDataPlane (http://opendataplane.org, ODP) is open source > (BSD-license) > +framework to support networking on different platforms and architectures. > +Current daq module implements odp functionality to listen for > +traffic on hardware optimized NICs. > + > +How to build: > + autoreconf -ivf > + ./configure > + make > diff --git a/configure.ac b/configure.ac > new file mode 100644 > index 0000000..425caca > --- /dev/null > +++ b/configure.ac > @@ -0,0 +1,43 @@ > +# > -*- Autoconf -*- > +# Process this file with autoconf to produce a configure script. > + > +AC_PREREQ(2.62) > +AC_INIT([odp-daq-module], [0.1], [maxim.uvarov@linaro.org]) > +AM_INIT_AUTOMAKE([daq], [0.1]) > +AC_CONFIG_MACRO_DIR([m4]) > +AC_CONFIG_SRCDIR([daq_odp.c]) > +AC_CONFIG_HEADERS([config.h]) > + > +# Checks for programs. > +AC_PROG_CC > +AC_PROG_LIBTOOL > + > +# Enable visibility if we can > +AC_ENABLE_VISIBILITY() > +# Special compiler flags for ICC, etc. > +AC_SF_COMPILER_SETUP() > + > +# Checks for the DAQ API headers and the SFBPF headers/library. > +AC_CHECK_DAQ_API > +AC_CHECK_SFBPF > + > +# Checks for other dependencies of your DAQ module go here. > + > + > +# Checks for header files. > +AC_CHECK_HEADERS([netinet/in.h stdint.h stdlib.h string.h]) > + > +# Checks for typedefs, structures, and compiler characteristics. > +AC_TYPE_SIZE_T > +AC_TYPE_UINT32_T > +AC_TYPE_UINT8_T > + > +# Checks for library functions. > +AC_FUNC_MALLOC > +AC_CHECK_FUNCS([memset strchr strdup strerror strtol]) > + > +# Substitutions > + > +# Output > +AC_CONFIG_FILES([Makefile]) > +AC_OUTPUT > diff --git a/daq_odp.c b/daq_odp.c > new file mode 100644 > index 0000000..c7983bc > --- /dev/null > +++ b/daq_odp.c > @@ -0,0 +1,394 @@ > +/* > + ** Copyright (c) 2014, Linaro Limited > + ** All rights reserved. > + ** > + ** SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#ifdef HAVE_CONFIG_H > +#include "config.h" > +#endif > + > +#include <errno.h> > +#include <linux/if_ether.h> > +#include <linux/if_packet.h> > +#include <net/if.h> > +#include <net/if_arp.h> > +#include <netinet/in.h> > +#include <stdint.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > +#include <sys/ioctl.h> > +#include <sys/mman.h> > +#include <sys/poll.h> > +#include <sys/socket.h> > +#include <unistd.h> > + > +#include "daq_api.h" > +#include "sfbpf.h" > + > +#include <odp.h> > +#include <helper/odp_linux.h> > +#include <helper/odp_packet_helper.h> > +#include <helper/odp_eth.h> > +#include <helper/odp_ip.h> > + > +#define MAX_WORKERS 1 > +#define SHM_PKT_POOL_SIZE (512*2048) > +#define SHM_PKT_POOL_BUF_SIZE 1856 > +#define MAX_PKT_BURST 16 > +#define ODP_DEBUG 1 > + > +typedef struct _odp_context > +{ > + volatile int break_loop; > + DAQ_Stats_t stats; > + DAQ_State state; > + odp_queue_t inq_def; > + odp_pktio_t pktio; > + int snaplen; > + char *device; > + char errbuf[256]; > +} ODP_Context_t; > + > +static int odp_daq_initialize(const DAQ_Config_t *config, void > **ctxt_ptr, char *errbuf, size_t errlen) > +{ > + ODP_Context_t *odpc; > + int rval = DAQ_ERROR; > + int thr_id; > + odp_buffer_pool_t pool; > + odp_pktio_params_t params; > + socket_params_t *sock_params = ¶ms.sock_params; > + odp_queue_param_t qparam; > + char inq_name[ODP_QUEUE_NAME_LEN]; > + int ret; > + void *pool_base; > + > + rval = DAQ_ERROR; > + > + odpc = calloc(1, sizeof(ODP_Context_t)); > + if (!odpc) > + { > + snprintf(errbuf, errlen, "%s: Couldn't allocate memory for > the new ODP context!", __FUNCTION__); > + rval = DAQ_ERROR_NOMEM; > + goto err; > + } > + > + odpc->device = strdup(config->name); > + if (!odpc->device) > + { > + snprintf(errbuf, errlen, "%s: Couldn't allocate memory for > the device string!", __FUNCTION__); > + rval = DAQ_ERROR_NOMEM; > + goto err; > + } > + > + *ctxt_ptr = odpc; > + > + /* Init ODP before calling anything else */ > + if (odp_init_global()) { > + ODP_ERR("Error: ODP global init failed.\n"); > + goto err; > + } > + > + /* Init this thread */ > + thr_id = odp_thread_create(0); > + odp_init_local(thr_id); > + > + /* Create packet pool */ > + pool_base = odp_shm_reserve("shm_packet_pool", > + SHM_PKT_POOL_SIZE, > ODP_CACHE_LINE_SIZE); > + if (pool_base == NULL) { > + ODP_ERR("Error: packet pool mem alloc failed.\n"); > + rval = DAQ_ERROR_NOMEM; > + goto err; > + } > + > + pool = odp_buffer_pool_create("packet_pool", pool_base, > + SHM_PKT_POOL_SIZE, > + SHM_PKT_POOL_BUF_SIZE, > + ODP_CACHE_LINE_SIZE, > + ODP_BUFFER_TYPE_PACKET); > + if (pool == ODP_BUFFER_POOL_INVALID) { > + ODP_ERR("Error: packet pool create failed.\n"); > + rval = DAQ_ERROR; > + goto err; > + } > + odpc->snaplen = SHM_PKT_POOL_BUF_SIZE; > + odp_buffer_pool_print(pool); > + > + /* Open a packet IO instance for this thread */ > + sock_params->type = ODP_PKTIO_TYPE_SOCKET_MMAP; > + sock_params->fanout = 0; > + > + odpc->pktio = odp_pktio_open(odpc->device, pool, ¶ms); > + if (odpc->pktio == ODP_PKTIO_INVALID) { > + ODP_ERR(" [%02i] Error: pktio create failed\n", 1 > /*thr*/); > + rval = DAQ_ERROR_NODEV; > + goto err; > + } > + > + /* > + * Create and set the default INPUT queue associated with the > 'pktio' > + * resource > + */ > + qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; > + qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; > + qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; > + snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", > (int)odpc->pktio); > + inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; > + > + odpc->inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, > &qparam); > + if (odpc->inq_def == ODP_QUEUE_INVALID) { > + ODP_ERR(" [%02i] Error: pktio queue creation failed\n", 1 > /*thr*/); > + goto err; > + } > + > + ret = odp_pktio_inq_setdef(odpc->pktio, odpc->inq_def); > + if (ret != 0) { > + ODP_ERR(" [%02i] Error: default input-Q setup\n", 1 > /*thr*/); > + goto err; > + } > + > + odpc->state = DAQ_STATE_INITIALIZED; > + > + printf("%s() DAQ_SUCCESS.\n\n", __func__); > + return DAQ_SUCCESS; > +err: > + > + return rval; > +} > + > +static int odp_daq_set_filter(void *handle, const char *filter) > +{ > + /* not implemented yet */ > + return DAQ_SUCCESS; > +} > + > +static int odp_daq_start(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + if (!odpc) > + return DAQ_ERROR_NOCTX; > + > + odpc->state = DAQ_STATE_STARTED; > + return DAQ_SUCCESS; > +} > + > +static const DAQ_Verdict verdict_translation_table[MAX_DAQ_VERDICT] = { > + DAQ_VERDICT_PASS, /* DAQ_VERDICT_PASS */ > + DAQ_VERDICT_BLOCK, /* DAQ_VERDICT_BLOCK */ > + DAQ_VERDICT_PASS, /* DAQ_VERDICT_REPLACE */ > + DAQ_VERDICT_PASS, /* DAQ_VERDICT_WHITELIST */ > + DAQ_VERDICT_BLOCK, /* DAQ_VERDICT_BLACKLIST */ > + DAQ_VERDICT_PASS /* DAQ_VERDICT_IGNORE */ > +}; > + > +static int odp_daq_acquire(void *handle, int cnt, DAQ_Analysis_Func_t > callback, DAQ_Meta_Func_t metaback, void *user) > +{ > + ODP_Context_t *odpc; > + DAQ_PktHdr_t daqhdr; > + DAQ_Verdict verdict; > + const uint8_t *data; > + odp_packet_t pkt; > + int i; > + odp_packet_t pkt_tbl[MAX_PKT_BURST]; > + int pkts; > + > + odpc = (ODP_Context_t *) handle; > + if (!odpc) > + return DAQ_ERROR; > + > + if (odpc->state != DAQ_STATE_STARTED) > + return DAQ_ERROR; > + > + while (1) > + { > + /* Has breakloop() been called? */ > + if (odpc->break_loop) > + { > + odpc->break_loop = 0; > + return 0; > + } > + > + pkts = odp_pktio_recv(odpc->pktio, pkt_tbl, MAX_PKT_BURST); > + if (pkts <= 0) { > + return 0; > + } > + > + for (i = 0; i < pkts; ++i) { > + pkt = pkt_tbl[i]; > + > + data = odp_packet_l2(pkt); > + if (!data) { > + //printf("no l2 offset, packet dropped\n"); > + odpc->stats.packets_filtered++; > + odp_buffer_free(pkt); > + continue; > + } > + > + verdict = DAQ_VERDICT_PASS; > + > + gettimeofday(&daqhdr.ts, NULL); > + daqhdr.caplen = odp_buffer_size(pkt); > + > + daqhdr.pktlen = odp_packet_get_len(pkt); > + daqhdr.ingress_index = 0; > + daqhdr.egress_index = DAQ_PKTHDR_UNKNOWN; > + daqhdr.ingress_group = DAQ_PKTHDR_UNKNOWN; > + daqhdr.egress_group = DAQ_PKTHDR_UNKNOWN; > + daqhdr.flags = 0; > + daqhdr.opaque = 0; > + daqhdr.priv_ptr = NULL; > + daqhdr.address_space_id = 0; > + > + if (callback) > + { > + verdict = callback(user, &daqhdr, data); > + if (verdict >= MAX_DAQ_VERDICT) > + verdict = DAQ_VERDICT_PASS; > + odpc->stats.verdicts[verdict]++; > + verdict = > verdict_translation_table[verdict]; > + } > + > + odp_buffer_free(pkt); > + } > + > + if (pkts > 0) { > + odpc->stats.packets_received += pkts; > + break; > + } > + } > + return 0; > +} > + > +static int odp_daq_inject(void *handle, const DAQ_PktHdr_t *hdr, const > uint8_t *packet_data, uint32_t len, int reverse) > +{ > + return DAQ_SUCCESS; > +} > + > +static int odp_daq_breakloop(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + odpc->break_loop = 1; > + return DAQ_SUCCESS; > +} > + > +static int odp_daq_stop(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + odpc->break_loop = 1; > + odp_timer_disarm_all(); > + odpc->state = DAQ_STATE_STOPPED; > + > + return DAQ_SUCCESS; > +} > + > +static void odp_daq_shutdown(void *handle) > +{ > + odp_timer_disarm_all(); > +} > + > +static DAQ_State odp_daq_check_status(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + if (!odpc) { > + return DAQ_STATE_UNINITIALIZED; > + } > + > + return odpc->state; > +} > + > +static int odp_daq_get_stats(void *handle, DAQ_Stats_t *stats) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + memcpy(stats, &odpc->stats, sizeof(DAQ_Stats_t)); > + return DAQ_SUCCESS; > +} > + > +static void odp_daq_reset_stats(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + memset(&odpc->stats, 0, sizeof(DAQ_Stats_t)); > +} > + > +static int odp_daq_get_snaplen(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + if (odpc) > + return odpc->snaplen; > + > + return 1500; > +} > + > +static uint32_t odp_daq_get_capabilities(void *handle) > +{ > + return DAQ_CAPA_BLOCK | DAQ_CAPA_REPLACE | DAQ_CAPA_BREAKLOOP | > DAQ_CAPA_DEVICE_INDEX; > +} > + > +static int odp_daq_get_datalink_type(void *handle) > +{ > + return DLT_EN10MB; > +} > + > +static const char *odp_daq_get_errbuf(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + return odpc->errbuf; > +} > + > +static void odp_daq_set_errbuf(void *handle, const char *string) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + if (!string) > + return; > + > + DPE(odpc->errbuf, "%s", string); > + return; > +} > + > +static int odp_daq_get_device_index(void *handle, const char *string) > +{ > + return DAQ_ERROR_NOTSUP; > +} > + > +#ifdef BUILDING_SO > +DAQ_SO_PUBLIC const DAQ_Module_t DAQ_MODULE_DATA = > +#else > +const DAQ_Module_t afpacket_daq_module_data = > +#endif > +{ > + .api_version = DAQ_API_VERSION, > + .module_version = 1, > + .name = "odp", > + .type = DAQ_TYPE_INTF_CAPABLE | DAQ_TYPE_INLINE_CAPABLE | > DAQ_TYPE_MULTI_INSTANCE, > + .initialize = odp_daq_initialize, > + .set_filter = odp_daq_set_filter, > + .start = odp_daq_start, > + .acquire = odp_daq_acquire, > + .inject = odp_daq_inject, > + .breakloop = odp_daq_breakloop, > + .stop = odp_daq_stop, > + .shutdown = odp_daq_shutdown, > + .check_status = odp_daq_check_status, > + .get_stats = odp_daq_get_stats, > + .reset_stats = odp_daq_reset_stats, > + .get_snaplen = odp_daq_get_snaplen, > + .get_capabilities = odp_daq_get_capabilities, > + .get_datalink_type = odp_daq_get_datalink_type, > + .get_errbuf = odp_daq_get_errbuf, > + .set_errbuf = odp_daq_set_errbuf, > + .get_device_index = odp_daq_get_device_index, > + .modify_flow = NULL, > + .hup_prep = NULL, > + .hup_apply = NULL, > + .hup_post = NULL, > +}; > diff --git a/m4/ax_cflags_gcc_option.m4 b/m4/ax_cflags_gcc_option.m4 > new file mode 100644 > index 0000000..22e6b53 > --- /dev/null > +++ b/m4/ax_cflags_gcc_option.m4 > @@ -0,0 +1,221 @@ > +# > =========================================================================== > +# http://www.nongnu.org/autoconf-archive/ax_cflags_gcc_option.html > +# > =========================================================================== > +# > +# SYNOPSIS > +# > +# AX_CFLAGS_GCC_OPTION (optionflag [,[shellvar][,[A][,[NA]]]) > +# > +# DESCRIPTION > +# > +# AX_CFLAGS_GCC_OPTION(-fvomit-frame) would show a message as like > +# "checking CFLAGS for gcc -fvomit-frame ... yes" and adds the > optionflag > +# to CFLAGS if it is understood. You can override the shellvar-default > of > +# CFLAGS of course. The order of arguments stems from the explicit > macros > +# like AX_CFLAGS_WARN_ALL. > +# > +# The cousin AX_CXXFLAGS_GCC_OPTION would check for an option to add to > +# CXXFLAGS - and it uses the autoconf setup for C++ instead of C (since > it > +# is possible to use different compilers for C and C++). > +# > +# The macro is a lot simpler than any special AX_CFLAGS_* macro (or > +# ax_cxx_rtti.m4 macro) but allows to check for arbitrary options. > +# However, if you use this macro in a few places, it would be great if > you > +# would make up a new function-macro and submit it to the ac-archive. > +# > +# - $1 option-to-check-for : required ("-option" as non-value) > +# - $2 shell-variable-to-add-to : CFLAGS (or CXXFLAGS in the other > case) > +# - $3 action-if-found : add value to shellvariable > +# - $4 action-if-not-found : nothing > +# > +# Note: in earlier versions, $1-$2 were swapped. We try to detect the > +# situation and accept a $2=~/-/ as being the old option-to-check-for. > +# > +# There are other variants that emerged from the original macro variant > +# which did just test an option to be possibly added. However, some > +# compilers accept an option silently, or possibly for just another > option > +# that was not intended. Therefore, we have to do a generic test for a > +# compiler family. For gcc we check "-pedantic" being accepted which is > +# also understood by compilers who just want to be compatible with gcc > +# even when not being made from gcc sources. > +# > +# See also: AX_CFLAGS_SUN_OPTION, AX_CFLAGS_HPUX_OPTION, > +# AX_CFLAGS_AIX_OPTION, and AX_CFLAGS_IRIX_OPTION. > +# > +# LICENSE > +# > +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> > +# > +# This program is free software; you can redistribute it and/or modify > it > +# under the terms of the GNU General Public License as published by the > +# Free Software Foundation; either version 2 of the License, or (at your > +# option) any later version. > +# > +# This program is distributed in the hope that it will be useful, but > +# WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > General > +# Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > along > +# with this program. If not, see <http://www.gnu.org/licenses/>. > +# > +# As a special exception, the respective Autoconf Macro's copyright > owner > +# gives unlimited permission to copy, distribute and modify the > configure > +# scripts that are the output of Autoconf when processing the Macro. You > +# need not follow the terms of the GNU General Public License when using > +# or distributing such scripts, even though portions of the text of the > +# Macro appear in them. The GNU General Public License (GPL) does govern > +# all other use of the material that constitutes the Autoconf Macro. > +# > +# This special exception to the GPL applies to versions of the Autoconf > +# Macro released by the Autoconf Archive. When you make and distribute a > +# modified version of the Autoconf Macro, you may extend this special > +# exception to the GPL to apply to your modified version as well. > + > +#serial 7 > + > +AC_DEFUN([AX_CFLAGS_GCC_OPTION_OLD], [dnl > +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl > +AS_VAR_PUSHDEF([VAR],[ax_cv_cflags_gcc_option_$2])dnl > +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)], > +VAR,[VAR="no, unknown" > + AC_LANG_SAVE > + AC_LANG_C > + ac_save_[]FLAGS="$[]FLAGS" > +for ac_arg dnl > +in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC > + "-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC > + # > +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` > + AC_TRY_COMPILE([],[return 0;], > + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) > +done > + FLAGS="$ac_save_[]FLAGS" > + AC_LANG_RESTORE > +]) > +case ".$VAR" in > + .ok|.ok,*) m4_ifvaln($3,$3) ;; > + .|.no|.no,*) m4_ifvaln($4,$4) ;; > + *) m4_ifvaln($3,$3,[ > + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null > + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) > + else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) > $VAR"]) > + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" > + fi ]) ;; > +esac > +AS_VAR_POPDEF([VAR])dnl > +AS_VAR_POPDEF([FLAGS])dnl > +]) > + > + > +dnl the only difference - the LANG selection... and the default FLAGS > + > +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_OLD], [dnl > +AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl > +AS_VAR_PUSHDEF([VAR],[ax_cv_cxxflags_gcc_option_$2])dnl > +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)], > +VAR,[VAR="no, unknown" > + AC_LANG_SAVE > + AC_LANG_CPLUSPLUS > + ac_save_[]FLAGS="$[]FLAGS" > +for ac_arg dnl > +in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC > + "-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC > + # > +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` > + AC_TRY_COMPILE([],[return 0;], > + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) > +done > + FLAGS="$ac_save_[]FLAGS" > + AC_LANG_RESTORE > +]) > +case ".$VAR" in > + .ok|.ok,*) m4_ifvaln($3,$3) ;; > + .|.no|.no,*) m4_ifvaln($4,$4) ;; > + *) m4_ifvaln($3,$3,[ > + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null > + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) > + else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) > $VAR"]) > + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" > + fi ]) ;; > +esac > +AS_VAR_POPDEF([VAR])dnl > +AS_VAR_POPDEF([FLAGS])dnl > +]) > + > +dnl > ------------------------------------------------------------------------- > + > +AC_DEFUN([AX_CFLAGS_GCC_OPTION_NEW], [dnl > +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl > > +AS_VAR_PUSHDEF([VAR],[ax_cv_cflags_gcc_option_[]m4_translit([[$1]],[=],[_])])dnl > +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], > +VAR,[VAR="no, unknown" > + AC_LANG_SAVE > + AC_LANG_C > + ac_save_[]FLAGS="$[]FLAGS" > +for ac_arg dnl > +in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC > + "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC > + # > +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` > + AC_TRY_COMPILE([],[return 0;], > + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) > +done > + FLAGS="$ac_save_[]FLAGS" > + AC_LANG_RESTORE > +]) > +case ".$VAR" in > + .ok|.ok,*) m4_ifvaln($3,$3) ;; > + .|.no|.no,*) m4_ifvaln($4,$4) ;; > + *) m4_ifvaln($3,$3,[ > + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null > + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) > + else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) > $VAR"]) > + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" > + fi ]) ;; > +esac > +AS_VAR_POPDEF([VAR])dnl > +AS_VAR_POPDEF([FLAGS])dnl > +]) > + > + > +dnl the only difference - the LANG selection... and the default FLAGS > + > +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_NEW], [dnl > +AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl > +AS_VAR_PUSHDEF([VAR],[ax_cv_cxxflags_gcc_option_$1])dnl > +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], > +VAR,[VAR="no, unknown" > + AC_LANG_SAVE > + AC_LANG_CPLUSPLUS > + ac_save_[]FLAGS="$[]FLAGS" > +for ac_arg dnl > +in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC > + "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC > + # > +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` > + AC_TRY_COMPILE([],[return 0;], > + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) > +done > + FLAGS="$ac_save_[]FLAGS" > + AC_LANG_RESTORE > +]) > +case ".$VAR" in > + .ok|.ok,*) m4_ifvaln($3,$3) ;; > + .|.no|.no,*) m4_ifvaln($4,$4) ;; > + *) m4_ifvaln($3,$3,[ > + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null > + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) > + else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) > $VAR"]) > + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" > + fi ]) ;; > +esac > +AS_VAR_POPDEF([VAR])dnl > +AS_VAR_POPDEF([FLAGS])dnl > +]) > + > +AC_DEFUN([AX_CFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, > +[AX_CFLAGS_GCC_OPTION_NEW($@)],[AX_CFLAGS_GCC_OPTION_OLD($@)])]) > + > +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, > +[AX_CXXFLAGS_GCC_OPTION_NEW($@)],[AX_CXXFLAGS_GCC_OPTION_OLD($@)])]) > diff --git a/m4/sf.m4 b/m4/sf.m4 > new file mode 100644 > index 0000000..547a993 > --- /dev/null > +++ b/m4/sf.m4 > @@ -0,0 +1,198 @@ > +dnl Enable visibility if we can > +dnl modified from gnulib/m4/visibility.m4 > +AC_DEFUN([AC_ENABLE_VISIBILITY], > +[ > + AC_REQUIRE([AC_PROG_CC]) > + AC_MSG_CHECKING([for visibility support]) > + AC_CACHE_VAL(gl_cv_cc_visibility, [ > + gl_save_CFLAGS="$CFLAGS" > + # Add -Werror flag since some compilers, e.g. icc 7.1, don't > support it, > + # but only warn about it instead of compilation failing > + CFLAGS="$CFLAGS -Werror -fvisibility=hidden" > + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ > + extern __attribute__((__visibility__("hidden"))) int > hiddenvar; > + extern __attribute__((__visibility__("default"))) int > exportedvar; > + extern __attribute__((__visibility__("hidden"))) int > hiddenfunc (void); > + extern __attribute__((__visibility__("default"))) int > exportedfunc (void);]], > + [[]])], > + [gl_cv_cc_visibility="yes"], > + [gl_cv_cc_visibility="no"]) > + ]) > + AC_MSG_RESULT([$gl_cv_cc_visibility]) > + if test "x$gl_cv_cc_visibility" = "xyes"; then > + CFLAGS="$gl_save_CFLAGS -fvisibility=hidden" > + AC_DEFINE([HAVE_VISIBILITY],[1], > + [Define if the compiler supports visibility declarations.]) > + else > + CFLAGS="$gl_save_CFLAGS" > + fi > +]) > + > +dnl Special compiler flags for ICC > +dnl GCC strict CFLAGS > +AC_DEFUN([AC_SF_COMPILER_SETUP], > + [AC_REQUIRE([AC_PROG_CC]) > + ICC=no > + if eval "echo $CC | grep icc > /dev/null" ; then > + if eval "$CC -help | grep libcxa > /dev/null" ; then > + CFLAGS="$CFLAGS -static-libcxa" > + LDFLAGS="$LDFLAGS -static-libcxa" > + XCCFLAGS="-XCClinker -static-libcxa" > + else > + CFLAGS="$CFLAGS -static-intel" > + LDFLAGS="$LDFLAGS -static-intel" > + XCCFLAGS="-XCClinker -static-intel" > + fi > + CFLAGS=`echo $CFLAGS | sed 's/-O2/-O3/'` > + CFLAGS="$CFLAGS -ip -w1" > + ICC=yes > + GCC=no > + fi > + > + if test "$GCC" = yes ; then > + AX_CFLAGS_GCC_OPTION(-Wall) > + AX_CFLAGS_GCC_OPTION(-Wwrite-strings) > + AX_CFLAGS_GCC_OPTION(-Wsign-compare) > + AX_CFLAGS_GCC_OPTION(-Wcast-align) > + AX_CFLAGS_GCC_OPTION(-Wextra) > + AX_CFLAGS_GCC_OPTION(-Wformat) > + AX_CFLAGS_GCC_OPTION(-Wformat-security) > + AX_CFLAGS_GCC_OPTION(-Wno-unused-parameter) > + AX_CFLAGS_GCC_OPTION(-fno-strict-aliasing) > + AX_CFLAGS_GCC_OPTION(-fdiagnostics-show-option) > + AX_CFLAGS_GCC_OPTION(-pedantic -std=c99 -D_GNU_SOURCE) > + fi > +]) > + > +dnl > +dnl Check for flex, default to lex > +dnl Require flex 2.4 or higher > +dnl Check for bison, default to yacc > +dnl Default to lex/yacc if both flex and bison are not available > +dnl Define the yy prefix string if using flex and bison > +dnl > +dnl usage: > +dnl > +dnl AC_LBL_LEX_AND_YACC(lex, yacc, yyprefix) > +dnl > +dnl results: > +dnl > +dnl $1 (lex set) > +dnl $2 (yacc appended) > +dnl $3 (optional flex and bison -P prefix) > +dnl > +AC_DEFUN([AC_LBL_LEX_AND_YACC], > + [AC_ARG_WITH(flex, [ --without-flex don't use flex]) > + AC_ARG_WITH(bison, [ --without-bison don't use bison]) > + if test "$with_flex" = no ; then > + $1=lex > + else > + AC_CHECK_PROGS($1, flex, lex) > + fi > + if test "$$1" = flex ; then > + # The -V flag was added in 2.4 > + AC_MSG_CHECKING(for flex 2.4 or higher) > + AC_CACHE_VAL(ac_cv_lbl_flex_v24, > + if flex -V >/dev/null 2>&1; then > + ac_cv_lbl_flex_v24=yes > + else > + ac_cv_lbl_flex_v24=no > + fi) > + AC_MSG_RESULT($ac_cv_lbl_flex_v24) > + if test $ac_cv_lbl_flex_v24 = no ; then > + s="2.4 or higher required" > + AC_MSG_WARN(ignoring obsolete flex executable ($s)) > + $1=lex > + fi > + fi > + if test "$with_bison" = no ; then > + $2=yacc > + else > + AC_CHECK_PROGS($2, bison, yacc) > + fi > + if test "$$2" = bison ; then > + $2="$$2 -y" > + fi > + if test "$$1" != lex -a "$$2" = yacc -o "$$1" = lex -a "$$2" != yacc > ; then > + AC_MSG_WARN(don't have both flex and bison; reverting to lex/yacc) > + $1=lex > + $2=yacc > + fi > + if test "$$1" = flex -a -n "$3" ; then > + $1="$$1 -P$3" > + $2="$$2 -p $3" > + fi]) > + > +AC_DEFUN([AC_CHECK_PCAP_VER], > +[ > + AC_REQUIRE([AC_PROG_CC]) > + AC_MSG_CHECKING([for pcap_lib_version]) > + AC_CHECK_LIB([pcap],[pcap_lib_version],[LIBS="-lpcap > ${LIBS}"],[have_pcap_lib_version="no"],[]) > + if test "x$have_pcap_lib_version" = "xno"; then > + echo > + echo " ERROR! Libpcap library version >= $1 not found." > + echo " Get it from http://www.tcpdump.org" > + echo > + exit 1 > + fi > + AC_MSG_CHECKING([for libpcap version >= $1]) > + AC_RUN_IFELSE( > + [AC_LANG_PROGRAM( > + [[ > + #include <pcap.h> > + #include <string.h> > + extern char pcap_version[]; > + ]], > + [[ > + if (strcmp(pcap_version, $1) < 0) > + return 1; > + ]])], > + [libpcap_version_1x="yes"], > + [libpcap_version_1x="no"]) > + if test "x$libpcap_version_1x" = "xno"; then > + AC_MSG_RESULT(no) > + echo > + echo " ERROR! Libpcap library version >= $1 not found." > + echo " Get it from http://www.tcpdump.org" > + echo > + exit 1 > + else > + AC_MSG_RESULT(yes) > + fi > +]) > + > +AC_DEFUN([AC_CHECK_DAQ_API], > +[ > + AC_ARG_WITH(libdaq_includes, > + [ --with-libdaq-includes=DIR libdaq include > directory], > + [with_daq_includes="$withval"], [with_daq_includes="no"]) > + > + if test "x$with_daq_includes" != "xno"; then > + CPPFLAGS="${CPPFLAGS} -I${with_daq_includes}" > + fi > + > + AC_CHECK_HEADER([daq_api.h], [], [AC_MSG_ERROR([Could not find > daq_api.h!])]) > +]) > + > +AC_DEFUN([AC_CHECK_SFBPF], > +[ > + AC_ARG_WITH(libsfbpf_includes, > + [ --with-libsfbpf-includes=DIR libsfbpf include > directory], > + [with_sfbpf_includes="$withval"], > [with_sfbpf_includes="no"]) > + > + AC_ARG_WITH(libsfbpf_libraries, > + [ --with-libsfbpf-libraries=DIR libsfbpf library > directory], > + [with_sfbpf_libraries="$withval"], > [with_sfbpf_libraries="no"]) > + > + if test "x$with_sfbpf_includes" != "xno"; then > + CPPFLAGS="${CPPFLAGS} -I${with_sfbpf_includes}" > + fi > + > + if test "x$with_sfbpf_libraries" != "xno"; then > + LDFLAGS="${LDFLAGS} -L${with_sfbpf_libraries}" > + fi > + > + AC_CHECK_HEADER([sfbpf.h], [], [AC_MSG_ERROR([Could not find > sfbpf.h!])]) > + AC_CHECK_LIB([sfbpf], [sfbpf_compile], [], [AC_MSG_ERROR([Could not > link against the SFBPF library!])]) > +]) > + > -- > 1.8.5.1.163.gd7aced9 > > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > http://lists.linaro.org/mailman/listinfo/lng-odp >
On 07/31/2014 06:12 PM, Mike Holmes wrote: > > > On 31 July 2014 10:01, Maxim Uvarov <maxim.uvarov@linaro.org > <mailto:maxim.uvarov@linaro.org>> wrote: > > Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org > <mailto:maxim.uvarov@linaro.org>> > --- > Hello, > > This is ODP Snort/DAQ module. The propose of this change is to > publish it > on github as separate project. Sending to our mailing list for > review/testing. > > Anders, please check if we need something more odp specific to m4 > scripts. > > I did compilation check and stress test blasting pcap to that module. > Can we migrate this test to LAVA ? > yes, but for that we need: 1. publish it somewhere. 2. build in OE. 3. run test in LAVA. Once 1 and 2 will be done, I think it's not hard to make this test in LAVA. Maxim. > > Thank you, > Maxim. > > > LICENSE | 29 ++++ > Makefile.am | 8 + > README | 9 ++ > configure.ac <http://configure.ac> | 43 +++++ > daq_odp.c | 394 > +++++++++++++++++++++++++++++++++++++++++++++ > m4/ax_cflags_gcc_option.m4 | 221 +++++++++++++++++++++++++ > m4/sf.m4 | 198 +++++++++++++++++++++++ > 7 files changed, 902 insertions(+) > create mode 100644 LICENSE > create mode 100644 Makefile.am > create mode 100644 README > create mode 100644 configure.ac <http://configure.ac> > create mode 100644 daq_odp.c > create mode 100644 m4/ax_cflags_gcc_option.m4 > create mode 100644 m4/sf.m4 > > diff --git a/LICENSE b/LICENSE > new file mode 100644 > index 0000000..441ba51 > --- /dev/null > +++ b/LICENSE > @@ -0,0 +1,29 @@ > +Copyright (c) 2013-2014, Linaro Limited > +All rights reserved. > + > +SPDX-License-Identifier: BSD-3-Clause > + > +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 Linaro Limited 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 HOLDER 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. > diff --git a/Makefile.am b/Makefile.am > new file mode 100644 > index 0000000..93c5cdf > --- /dev/null > +++ b/Makefile.am > @@ -0,0 +1,8 @@ > +AUTOMAKE_OPTIONS = foreign > + > +ACLOCAL_AMFLAGS = -I m4 > + > +pkglib_LTLIBRARIES = daq_odp.la <http://daq_odp.la> > +daq_example_la_SOURCES = daq_odp.c > +daq_example_la_CFLAGS = -DBUILDING_SO > +daq_example_la_LDFLAGS = -module -export-dynamic -avoid-version > -shared > diff --git a/README b/README > new file mode 100644 > index 0000000..eec4f87 > --- /dev/null > +++ b/README > @@ -0,0 +1,9 @@ > +OpenDataPlane (http://opendataplane.org, ODP) is open source > (BSD-license) > +framework to support networking on different platforms and > architectures. > +Current daq module implements odp functionality to listen for > +traffic on hardware optimized NICs. > + > +How to build: > + autoreconf -ivf > + ./configure > + make > diff --git a/configure.ac <http://configure.ac> b/configure.ac > <http://configure.ac> > new file mode 100644 > index 0000000..425caca > --- /dev/null > +++ b/configure.ac <http://configure.ac> > @@ -0,0 +1,43 @@ > +# -*- Autoconf -*- > +# Process this file with autoconf to produce a configure script. > + > +AC_PREREQ(2.62) > +AC_INIT([odp-daq-module], [0.1], [maxim.uvarov@linaro.org > <mailto:maxim.uvarov@linaro.org>]) > +AM_INIT_AUTOMAKE([daq], [0.1]) > +AC_CONFIG_MACRO_DIR([m4]) > +AC_CONFIG_SRCDIR([daq_odp.c]) > +AC_CONFIG_HEADERS([config.h]) > + > +# Checks for programs. > +AC_PROG_CC > +AC_PROG_LIBTOOL > + > +# Enable visibility if we can > +AC_ENABLE_VISIBILITY() > +# Special compiler flags for ICC, etc. > +AC_SF_COMPILER_SETUP() > + > +# Checks for the DAQ API headers and the SFBPF headers/library. > +AC_CHECK_DAQ_API > +AC_CHECK_SFBPF > + > +# Checks for other dependencies of your DAQ module go here. > + > + > +# Checks for header files. > +AC_CHECK_HEADERS([netinet/in.h stdint.h stdlib.h string.h]) > + > +# Checks for typedefs, structures, and compiler characteristics. > +AC_TYPE_SIZE_T > +AC_TYPE_UINT32_T > +AC_TYPE_UINT8_T > + > +# Checks for library functions. > +AC_FUNC_MALLOC > +AC_CHECK_FUNCS([memset strchr strdup strerror strtol]) > + > +# Substitutions > + > +# Output > +AC_CONFIG_FILES([Makefile]) > +AC_OUTPUT > diff --git a/daq_odp.c b/daq_odp.c > new file mode 100644 > index 0000000..c7983bc > --- /dev/null > +++ b/daq_odp.c > @@ -0,0 +1,394 @@ > +/* > + ** Copyright (c) 2014, Linaro Limited > + ** All rights reserved. > + ** > + ** SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#ifdef HAVE_CONFIG_H > +#include "config.h" > +#endif > + > +#include <errno.h> > +#include <linux/if_ether.h> > +#include <linux/if_packet.h> > +#include <net/if.h> > +#include <net/if_arp.h> > +#include <netinet/in.h> > +#include <stdint.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > +#include <sys/ioctl.h> > +#include <sys/mman.h> > +#include <sys/poll.h> > +#include <sys/socket.h> > +#include <unistd.h> > + > +#include "daq_api.h" > +#include "sfbpf.h" > + > +#include <odp.h> > +#include <helper/odp_linux.h> > +#include <helper/odp_packet_helper.h> > +#include <helper/odp_eth.h> > +#include <helper/odp_ip.h> > + > +#define MAX_WORKERS 1 > +#define SHM_PKT_POOL_SIZE (512*2048) > +#define SHM_PKT_POOL_BUF_SIZE 1856 > +#define MAX_PKT_BURST 16 > +#define ODP_DEBUG 1 > + > +typedef struct _odp_context > +{ > + volatile int break_loop; > + DAQ_Stats_t stats; > + DAQ_State state; > + odp_queue_t inq_def; > + odp_pktio_t pktio; > + int snaplen; > + char *device; > + char errbuf[256]; > +} ODP_Context_t; > + > +static int odp_daq_initialize(const DAQ_Config_t *config, void > **ctxt_ptr, char *errbuf, size_t errlen) > +{ > + ODP_Context_t *odpc; > + int rval = DAQ_ERROR; > + int thr_id; > + odp_buffer_pool_t pool; > + odp_pktio_params_t params; > + socket_params_t *sock_params = ¶ms.sock_params; > + odp_queue_param_t qparam; > + char inq_name[ODP_QUEUE_NAME_LEN]; > + int ret; > + void *pool_base; > + > + rval = DAQ_ERROR; > + > + odpc = calloc(1, sizeof(ODP_Context_t)); > + if (!odpc) > + { > + snprintf(errbuf, errlen, "%s: Couldn't allocate > memory for the new ODP context!", __FUNCTION__); > + rval = DAQ_ERROR_NOMEM; > + goto err; > + } > + > + odpc->device = strdup(config->name); > + if (!odpc->device) > + { > + snprintf(errbuf, errlen, "%s: Couldn't allocate > memory for the device string!", __FUNCTION__); > + rval = DAQ_ERROR_NOMEM; > + goto err; > + } > + > + *ctxt_ptr = odpc; > + > + /* Init ODP before calling anything else */ > + if (odp_init_global()) { > + ODP_ERR("Error: ODP global init failed.\n"); > + goto err; > + } > + > + /* Init this thread */ > + thr_id = odp_thread_create(0); > + odp_init_local(thr_id); > + > + /* Create packet pool */ > + pool_base = odp_shm_reserve("shm_packet_pool", > + SHM_PKT_POOL_SIZE, > ODP_CACHE_LINE_SIZE); > + if (pool_base == NULL) { > + ODP_ERR("Error: packet pool mem alloc failed.\n"); > + rval = DAQ_ERROR_NOMEM; > + goto err; > + } > + > + pool = odp_buffer_pool_create("packet_pool", pool_base, > + SHM_PKT_POOL_SIZE, > + SHM_PKT_POOL_BUF_SIZE, > + ODP_CACHE_LINE_SIZE, > + ODP_BUFFER_TYPE_PACKET); > + if (pool == ODP_BUFFER_POOL_INVALID) { > + ODP_ERR("Error: packet pool create failed.\n"); > + rval = DAQ_ERROR; > + goto err; > + } > + odpc->snaplen = SHM_PKT_POOL_BUF_SIZE; > + odp_buffer_pool_print(pool); > + > + /* Open a packet IO instance for this thread */ > + sock_params->type = ODP_PKTIO_TYPE_SOCKET_MMAP; > + sock_params->fanout = 0; > + > + odpc->pktio = odp_pktio_open(odpc->device, pool, ¶ms); > + if (odpc->pktio == ODP_PKTIO_INVALID) { > + ODP_ERR(" [%02i] Error: pktio create failed\n", 1 > /*thr*/); > + rval = DAQ_ERROR_NODEV; > + goto err; > + } > + > + /* > + * Create and set the default INPUT queue associated with > the 'pktio' > + * resource > + */ > + qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; > + qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; > + qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; > + snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", > (int)odpc->pktio); > + inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; > + > + odpc->inq_def = odp_queue_create(inq_name, > ODP_QUEUE_TYPE_PKTIN, &qparam); > + if (odpc->inq_def == ODP_QUEUE_INVALID) { > + ODP_ERR(" [%02i] Error: pktio queue creation > failed\n", 1 /*thr*/); > + goto err; > + } > + > + ret = odp_pktio_inq_setdef(odpc->pktio, odpc->inq_def); > + if (ret != 0) { > + ODP_ERR(" [%02i] Error: default input-Q setup\n", > 1 /*thr*/); > + goto err; > + } > + > + odpc->state = DAQ_STATE_INITIALIZED; > + > + printf("%s() DAQ_SUCCESS.\n\n", __func__); > + return DAQ_SUCCESS; > +err: > + > + return rval; > +} > + > +static int odp_daq_set_filter(void *handle, const char *filter) > +{ > + /* not implemented yet */ > + return DAQ_SUCCESS; > +} > + > +static int odp_daq_start(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + if (!odpc) > + return DAQ_ERROR_NOCTX; > + > + odpc->state = DAQ_STATE_STARTED; > + return DAQ_SUCCESS; > +} > + > +static const DAQ_Verdict > verdict_translation_table[MAX_DAQ_VERDICT] = { > + DAQ_VERDICT_PASS, /* DAQ_VERDICT_PASS */ > + DAQ_VERDICT_BLOCK, /* DAQ_VERDICT_BLOCK */ > + DAQ_VERDICT_PASS, /* DAQ_VERDICT_REPLACE */ > + DAQ_VERDICT_PASS, /* DAQ_VERDICT_WHITELIST */ > + DAQ_VERDICT_BLOCK, /* DAQ_VERDICT_BLACKLIST */ > + DAQ_VERDICT_PASS /* DAQ_VERDICT_IGNORE */ > +}; > + > +static int odp_daq_acquire(void *handle, int cnt, > DAQ_Analysis_Func_t callback, DAQ_Meta_Func_t metaback, void *user) > +{ > + ODP_Context_t *odpc; > + DAQ_PktHdr_t daqhdr; > + DAQ_Verdict verdict; > + const uint8_t *data; > + odp_packet_t pkt; > + int i; > + odp_packet_t pkt_tbl[MAX_PKT_BURST]; > + int pkts; > + > + odpc = (ODP_Context_t *) handle; > + if (!odpc) > + return DAQ_ERROR; > + > + if (odpc->state != DAQ_STATE_STARTED) > + return DAQ_ERROR; > + > + while (1) > + { > + /* Has breakloop() been called? */ > + if (odpc->break_loop) > + { > + odpc->break_loop = 0; > + return 0; > + } > + > + pkts = odp_pktio_recv(odpc->pktio, pkt_tbl, > MAX_PKT_BURST); > + if (pkts <= 0) { > + return 0; > + } > + > + for (i = 0; i < pkts; ++i) { > + pkt = pkt_tbl[i]; > + > + data = odp_packet_l2(pkt); > + if (!data) { > + //printf("no l2 offset, packet > dropped\n"); > + odpc->stats.packets_filtered++; > + odp_buffer_free(pkt); > + continue; > + } > + > + verdict = DAQ_VERDICT_PASS; > + > + gettimeofday(&daqhdr.ts, NULL); > + daqhdr.caplen = odp_buffer_size(pkt); > + > + daqhdr.pktlen = odp_packet_get_len(pkt); > + daqhdr.ingress_index = 0; > + daqhdr.egress_index = DAQ_PKTHDR_UNKNOWN; > + daqhdr.ingress_group = DAQ_PKTHDR_UNKNOWN; > + daqhdr.egress_group = DAQ_PKTHDR_UNKNOWN; > + daqhdr.flags = 0; > + daqhdr.opaque = 0; > + daqhdr.priv_ptr = NULL; > + daqhdr.address_space_id = 0; > + > + if (callback) > + { > + verdict = callback(user, &daqhdr, > data); > + if (verdict >= MAX_DAQ_VERDICT) > + verdict = DAQ_VERDICT_PASS; > + odpc->stats.verdicts[verdict]++; > + verdict = > verdict_translation_table[verdict]; > + } > + > + odp_buffer_free(pkt); > + } > + > + if (pkts > 0) { > + odpc->stats.packets_received += pkts; > + break; > + } > + } > + return 0; > +} > + > +static int odp_daq_inject(void *handle, const DAQ_PktHdr_t *hdr, > const uint8_t *packet_data, uint32_t len, int reverse) > +{ > + return DAQ_SUCCESS; > +} > + > +static int odp_daq_breakloop(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + odpc->break_loop = 1; > + return DAQ_SUCCESS; > +} > + > +static int odp_daq_stop(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + odpc->break_loop = 1; > + odp_timer_disarm_all(); > + odpc->state = DAQ_STATE_STOPPED; > + > + return DAQ_SUCCESS; > +} > + > +static void odp_daq_shutdown(void *handle) > +{ > + odp_timer_disarm_all(); > +} > + > +static DAQ_State odp_daq_check_status(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + if (!odpc) { > + return DAQ_STATE_UNINITIALIZED; > + } > + > + return odpc->state; > +} > + > +static int odp_daq_get_stats(void *handle, DAQ_Stats_t *stats) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + memcpy(stats, &odpc->stats, sizeof(DAQ_Stats_t)); > + return DAQ_SUCCESS; > +} > + > +static void odp_daq_reset_stats(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + memset(&odpc->stats, 0, sizeof(DAQ_Stats_t)); > +} > + > +static int odp_daq_get_snaplen(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + if (odpc) > + return odpc->snaplen; > + > + return 1500; > +} > + > +static uint32_t odp_daq_get_capabilities(void *handle) > +{ > + return DAQ_CAPA_BLOCK | DAQ_CAPA_REPLACE | > DAQ_CAPA_BREAKLOOP | DAQ_CAPA_DEVICE_INDEX; > +} > + > +static int odp_daq_get_datalink_type(void *handle) > +{ > + return DLT_EN10MB; > +} > + > +static const char *odp_daq_get_errbuf(void *handle) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + return odpc->errbuf; > +} > + > +static void odp_daq_set_errbuf(void *handle, const char *string) > +{ > + ODP_Context_t *odpc = (ODP_Context_t *) handle; > + > + if (!string) > + return; > + > + DPE(odpc->errbuf, "%s", string); > + return; > +} > + > +static int odp_daq_get_device_index(void *handle, const char *string) > +{ > + return DAQ_ERROR_NOTSUP; > +} > + > +#ifdef BUILDING_SO > +DAQ_SO_PUBLIC const DAQ_Module_t DAQ_MODULE_DATA = > +#else > +const DAQ_Module_t afpacket_daq_module_data = > +#endif > +{ > + .api_version = DAQ_API_VERSION, > + .module_version = 1, > + .name = "odp", > + .type = DAQ_TYPE_INTF_CAPABLE | DAQ_TYPE_INLINE_CAPABLE | > DAQ_TYPE_MULTI_INSTANCE, > + .initialize = odp_daq_initialize, > + .set_filter = odp_daq_set_filter, > + .start = odp_daq_start, > + .acquire = odp_daq_acquire, > + .inject = odp_daq_inject, > + .breakloop = odp_daq_breakloop, > + .stop = odp_daq_stop, > + .shutdown = odp_daq_shutdown, > + .check_status = odp_daq_check_status, > + .get_stats = odp_daq_get_stats, > + .reset_stats = odp_daq_reset_stats, > + .get_snaplen = odp_daq_get_snaplen, > + .get_capabilities = odp_daq_get_capabilities, > + .get_datalink_type = odp_daq_get_datalink_type, > + .get_errbuf = odp_daq_get_errbuf, > + .set_errbuf = odp_daq_set_errbuf, > + .get_device_index = odp_daq_get_device_index, > + .modify_flow = NULL, > + .hup_prep = NULL, > + .hup_apply = NULL, > + .hup_post = NULL, > +}; > diff --git a/m4/ax_cflags_gcc_option.m4 b/m4/ax_cflags_gcc_option.m4 > new file mode 100644 > index 0000000..22e6b53 > --- /dev/null > +++ b/m4/ax_cflags_gcc_option.m4 > @@ -0,0 +1,221 @@ > +# > =========================================================================== > +# http://www.nongnu.org/autoconf-archive/ax_cflags_gcc_option.html > +# > =========================================================================== > +# > +# SYNOPSIS > +# > +# AX_CFLAGS_GCC_OPTION (optionflag [,[shellvar][,[A][,[NA]]]) > +# > +# DESCRIPTION > +# > +# AX_CFLAGS_GCC_OPTION(-fvomit-frame) would show a message as like > +# "checking CFLAGS for gcc -fvomit-frame ... yes" and adds the > optionflag > +# to CFLAGS if it is understood. You can override the > shellvar-default of > +# CFLAGS of course. The order of arguments stems from the > explicit macros > +# like AX_CFLAGS_WARN_ALL. > +# > +# The cousin AX_CXXFLAGS_GCC_OPTION would check for an option > to add to > +# CXXFLAGS - and it uses the autoconf setup for C++ instead of > C (since it > +# is possible to use different compilers for C and C++). > +# > +# The macro is a lot simpler than any special AX_CFLAGS_* macro (or > +# ax_cxx_rtti.m4 macro) but allows to check for arbitrary options. > +# However, if you use this macro in a few places, it would be > great if you > +# would make up a new function-macro and submit it to the > ac-archive. > +# > +# - $1 option-to-check-for : required ("-option" as non-value) > +# - $2 shell-variable-to-add-to : CFLAGS (or CXXFLAGS in the > other case) > +# - $3 action-if-found : add value to shellvariable > +# - $4 action-if-not-found : nothing > +# > +# Note: in earlier versions, $1-$2 were swapped. We try to > detect the > +# situation and accept a $2=~/-/ as being the old > option-to-check-for. > +# > +# There are other variants that emerged from the original macro > variant > +# which did just test an option to be possibly added. However, some > +# compilers accept an option silently, or possibly for just > another option > +# that was not intended. Therefore, we have to do a generic > test for a > +# compiler family. For gcc we check "-pedantic" being accepted > which is > +# also understood by compilers who just want to be compatible > with gcc > +# even when not being made from gcc sources. > +# > +# See also: AX_CFLAGS_SUN_OPTION, AX_CFLAGS_HPUX_OPTION, > +# AX_CFLAGS_AIX_OPTION, and AX_CFLAGS_IRIX_OPTION. > +# > +# LICENSE > +# > +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de > <mailto:guidod@gmx.de>> > +# > +# This program is free software; you can redistribute it and/or > modify it > +# under the terms of the GNU General Public License as > published by the > +# Free Software Foundation; either version 2 of the License, or > (at your > +# option) any later version. > +# > +# This program is distributed in the hope that it will be > useful, but > +# WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > GNU General > +# Public License for more details. > +# > +# You should have received a copy of the GNU General Public > License along > +# with this program. If not, see <http://www.gnu.org/licenses/>. > +# > +# As a special exception, the respective Autoconf Macro's > copyright owner > +# gives unlimited permission to copy, distribute and modify the > configure > +# scripts that are the output of Autoconf when processing the > Macro. You > +# need not follow the terms of the GNU General Public License > when using > +# or distributing such scripts, even though portions of the > text of the > +# Macro appear in them. The GNU General Public License (GPL) > does govern > +# all other use of the material that constitutes the Autoconf > Macro. > +# > +# This special exception to the GPL applies to versions of the > Autoconf > +# Macro released by the Autoconf Archive. When you make and > distribute a > +# modified version of the Autoconf Macro, you may extend this > special > +# exception to the GPL to apply to your modified version as well. > + > +#serial 7 > + > +AC_DEFUN([AX_CFLAGS_GCC_OPTION_OLD], [dnl > +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl > +AS_VAR_PUSHDEF([VAR],[ax_cv_cflags_gcc_option_$2])dnl > +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc > m4_ifval($2,$2,-option)], > +VAR,[VAR="no, unknown" > + AC_LANG_SAVE > + AC_LANG_C > + ac_save_[]FLAGS="$[]FLAGS" > +for ac_arg dnl > +in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC > + "-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC > + # > +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e > 's,%,,'` > + AC_TRY_COMPILE([],[return 0;], > + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) > +done > + FLAGS="$ac_save_[]FLAGS" > + AC_LANG_RESTORE > +]) > +case ".$VAR" in > + .ok|.ok,*) m4_ifvaln($3,$3) ;; > + .|.no|.no,*) m4_ifvaln($4,$4) ;; > + *) m4_ifvaln($3,$3,[ > + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 > >/dev/null > + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) > + else AC_RUN_LOG([: > m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) > + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" > + fi ]) ;; > +esac > +AS_VAR_POPDEF([VAR])dnl > +AS_VAR_POPDEF([FLAGS])dnl > +]) > + > + > +dnl the only difference - the LANG selection... and the default FLAGS > + > +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_OLD], [dnl > +AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl > +AS_VAR_PUSHDEF([VAR],[ax_cv_cxxflags_gcc_option_$2])dnl > +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc > m4_ifval($2,$2,-option)], > +VAR,[VAR="no, unknown" > + AC_LANG_SAVE > + AC_LANG_CPLUSPLUS > + ac_save_[]FLAGS="$[]FLAGS" > +for ac_arg dnl > +in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC > + "-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC > + # > +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e > 's,%,,'` > + AC_TRY_COMPILE([],[return 0;], > + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) > +done > + FLAGS="$ac_save_[]FLAGS" > + AC_LANG_RESTORE > +]) > +case ".$VAR" in > + .ok|.ok,*) m4_ifvaln($3,$3) ;; > + .|.no|.no,*) m4_ifvaln($4,$4) ;; > + *) m4_ifvaln($3,$3,[ > + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 > >/dev/null > + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) > + else AC_RUN_LOG([: > m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) > + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" > + fi ]) ;; > +esac > +AS_VAR_POPDEF([VAR])dnl > +AS_VAR_POPDEF([FLAGS])dnl > +]) > + > +dnl > ------------------------------------------------------------------------- > + > +AC_DEFUN([AX_CFLAGS_GCC_OPTION_NEW], [dnl > +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl > +AS_VAR_PUSHDEF([VAR],[ax_cv_cflags_gcc_option_[]m4_translit([[$1]],[=],[_])])dnl > +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc > m4_ifval($1,$1,-option)], > +VAR,[VAR="no, unknown" > + AC_LANG_SAVE > + AC_LANG_C > + ac_save_[]FLAGS="$[]FLAGS" > +for ac_arg dnl > +in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC > + "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC > + # > +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e > 's,%,,'` > + AC_TRY_COMPILE([],[return 0;], > + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) > +done > + FLAGS="$ac_save_[]FLAGS" > + AC_LANG_RESTORE > +]) > +case ".$VAR" in > + .ok|.ok,*) m4_ifvaln($3,$3) ;; > + .|.no|.no,*) m4_ifvaln($4,$4) ;; > + *) m4_ifvaln($3,$3,[ > + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 > >/dev/null > + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) > + else AC_RUN_LOG([: > m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) > + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" > + fi ]) ;; > +esac > +AS_VAR_POPDEF([VAR])dnl > +AS_VAR_POPDEF([FLAGS])dnl > +]) > + > + > +dnl the only difference - the LANG selection... and the default FLAGS > + > +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_NEW], [dnl > +AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl > +AS_VAR_PUSHDEF([VAR],[ax_cv_cxxflags_gcc_option_$1])dnl > +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc > m4_ifval($1,$1,-option)], > +VAR,[VAR="no, unknown" > + AC_LANG_SAVE > + AC_LANG_CPLUSPLUS > + ac_save_[]FLAGS="$[]FLAGS" > +for ac_arg dnl > +in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC > + "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC > + # > +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e > 's,%,,'` > + AC_TRY_COMPILE([],[return 0;], > + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) > +done > + FLAGS="$ac_save_[]FLAGS" > + AC_LANG_RESTORE > +]) > +case ".$VAR" in > + .ok|.ok,*) m4_ifvaln($3,$3) ;; > + .|.no|.no,*) m4_ifvaln($4,$4) ;; > + *) m4_ifvaln($3,$3,[ > + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 > >/dev/null > + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) > + else AC_RUN_LOG([: > m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) > + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" > + fi ]) ;; > +esac > +AS_VAR_POPDEF([VAR])dnl > +AS_VAR_POPDEF([FLAGS])dnl > +]) > + > +AC_DEFUN([AX_CFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, > +[AX_CFLAGS_GCC_OPTION_NEW($@)],[AX_CFLAGS_GCC_OPTION_OLD($@)])]) > + > +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, > +[AX_CXXFLAGS_GCC_OPTION_NEW($@)],[AX_CXXFLAGS_GCC_OPTION_OLD($@)])]) > diff --git a/m4/sf.m4 b/m4/sf.m4 > new file mode 100644 > index 0000000..547a993 > --- /dev/null > +++ b/m4/sf.m4 > @@ -0,0 +1,198 @@ > +dnl Enable visibility if we can > +dnl modified from gnulib/m4/visibility.m4 > +AC_DEFUN([AC_ENABLE_VISIBILITY], > +[ > + AC_REQUIRE([AC_PROG_CC]) > + AC_MSG_CHECKING([for visibility support]) > + AC_CACHE_VAL(gl_cv_cc_visibility, [ > + gl_save_CFLAGS="$CFLAGS" > + # Add -Werror flag since some compilers, e.g. icc 7.1, > don't support it, > + # but only warn about it instead of compilation failing > + CFLAGS="$CFLAGS -Werror -fvisibility=hidden" > + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ > + extern __attribute__((__visibility__("hidden"))) int > hiddenvar; > + extern __attribute__((__visibility__("default"))) int > exportedvar; > + extern __attribute__((__visibility__("hidden"))) int > hiddenfunc (void); > + extern __attribute__((__visibility__("default"))) int > exportedfunc (void);]], > + [[]])], > + [gl_cv_cc_visibility="yes"], > + [gl_cv_cc_visibility="no"]) > + ]) > + AC_MSG_RESULT([$gl_cv_cc_visibility]) > + if test "x$gl_cv_cc_visibility" = "xyes"; then > + CFLAGS="$gl_save_CFLAGS -fvisibility=hidden" > + AC_DEFINE([HAVE_VISIBILITY],[1], > + [Define if the compiler supports visibility > declarations.]) > + else > + CFLAGS="$gl_save_CFLAGS" > + fi > +]) > + > +dnl Special compiler flags for ICC > +dnl GCC strict CFLAGS > +AC_DEFUN([AC_SF_COMPILER_SETUP], > + [AC_REQUIRE([AC_PROG_CC]) > + ICC=no > + if eval "echo $CC | grep icc > /dev/null" ; then > + if eval "$CC -help | grep libcxa > /dev/null" ; then > + CFLAGS="$CFLAGS -static-libcxa" > + LDFLAGS="$LDFLAGS -static-libcxa" > + XCCFLAGS="-XCClinker -static-libcxa" > + else > + CFLAGS="$CFLAGS -static-intel" > + LDFLAGS="$LDFLAGS -static-intel" > + XCCFLAGS="-XCClinker -static-intel" > + fi > + CFLAGS=`echo $CFLAGS | sed 's/-O2/-O3/'` > + CFLAGS="$CFLAGS -ip -w1" > + ICC=yes > + GCC=no > + fi > + > + if test "$GCC" = yes ; then > + AX_CFLAGS_GCC_OPTION(-Wall) > + AX_CFLAGS_GCC_OPTION(-Wwrite-strings) > + AX_CFLAGS_GCC_OPTION(-Wsign-compare) > + AX_CFLAGS_GCC_OPTION(-Wcast-align) > + AX_CFLAGS_GCC_OPTION(-Wextra) > + AX_CFLAGS_GCC_OPTION(-Wformat) > + AX_CFLAGS_GCC_OPTION(-Wformat-security) > + AX_CFLAGS_GCC_OPTION(-Wno-unused-parameter) > + AX_CFLAGS_GCC_OPTION(-fno-strict-aliasing) > + AX_CFLAGS_GCC_OPTION(-fdiagnostics-show-option) > + AX_CFLAGS_GCC_OPTION(-pedantic -std=c99 -D_GNU_SOURCE) > + fi > +]) > + > +dnl > +dnl Check for flex, default to lex > +dnl Require flex 2.4 or higher > +dnl Check for bison, default to yacc > +dnl Default to lex/yacc if both flex and bison are not available > +dnl Define the yy prefix string if using flex and bison > +dnl > +dnl usage: > +dnl > +dnl AC_LBL_LEX_AND_YACC(lex, yacc, yyprefix) > +dnl > +dnl results: > +dnl > +dnl $1 (lex set) > +dnl $2 (yacc appended) > +dnl $3 (optional flex and bison -P prefix) > +dnl > +AC_DEFUN([AC_LBL_LEX_AND_YACC], > + [AC_ARG_WITH(flex, [ --without-flex don't use flex]) > + AC_ARG_WITH(bison, [ --without-bison don't use bison]) > + if test "$with_flex" = no ; then > + $1=lex > + else > + AC_CHECK_PROGS($1, flex, lex) > + fi > + if test "$$1" = flex ; then > + # The -V flag was added in 2.4 > + AC_MSG_CHECKING(for flex 2.4 or higher) > + AC_CACHE_VAL(ac_cv_lbl_flex_v24, > + if flex -V >/dev/null 2>&1; then > + ac_cv_lbl_flex_v24=yes > + else > + ac_cv_lbl_flex_v24=no > + fi) > + AC_MSG_RESULT($ac_cv_lbl_flex_v24) > + if test $ac_cv_lbl_flex_v24 = no ; then > + s="2.4 or higher required" > + AC_MSG_WARN(ignoring obsolete flex executable ($s)) > + $1=lex > + fi > + fi > + if test "$with_bison" = no ; then > + $2=yacc > + else > + AC_CHECK_PROGS($2, bison, yacc) > + fi > + if test "$$2" = bison ; then > + $2="$$2 -y" > + fi > + if test "$$1" != lex -a "$$2" = yacc -o "$$1" = lex -a "$$2" > != yacc ; then > + AC_MSG_WARN(don't have both flex and bison; reverting to > lex/yacc) > + $1=lex > + $2=yacc > + fi > + if test "$$1" = flex -a -n "$3" ; then > + $1="$$1 -P$3" > + $2="$$2 -p $3" > + fi]) > + > +AC_DEFUN([AC_CHECK_PCAP_VER], > +[ > + AC_REQUIRE([AC_PROG_CC]) > + AC_MSG_CHECKING([for pcap_lib_version]) > + AC_CHECK_LIB([pcap],[pcap_lib_version],[LIBS="-lpcap > ${LIBS}"],[have_pcap_lib_version="no"],[]) > + if test "x$have_pcap_lib_version" = "xno"; then > + echo > + echo " ERROR! Libpcap library version >= $1 not found." > + echo " Get it from http://www.tcpdump.org" > + echo > + exit 1 > + fi > + AC_MSG_CHECKING([for libpcap version >= $1]) > + AC_RUN_IFELSE( > + [AC_LANG_PROGRAM( > + [[ > + #include <pcap.h> > + #include <string.h> > + extern char pcap_version[]; > + ]], > + [[ > + if (strcmp(pcap_version, $1) < 0) > + return 1; > + ]])], > + [libpcap_version_1x="yes"], > + [libpcap_version_1x="no"]) > + if test "x$libpcap_version_1x" = "xno"; then > + AC_MSG_RESULT(no) > + echo > + echo " ERROR! Libpcap library version >= $1 not found." > + echo " Get it from http://www.tcpdump.org" > + echo > + exit 1 > + else > + AC_MSG_RESULT(yes) > + fi > +]) > + > +AC_DEFUN([AC_CHECK_DAQ_API], > +[ > + AC_ARG_WITH(libdaq_includes, > + [ --with-libdaq-includes=DIR libdaq include > directory], > + [with_daq_includes="$withval"], > [with_daq_includes="no"]) > + > + if test "x$with_daq_includes" != "xno"; then > + CPPFLAGS="${CPPFLAGS} -I${with_daq_includes}" > + fi > + > + AC_CHECK_HEADER([daq_api.h], [], [AC_MSG_ERROR([Could not > find daq_api.h!])]) > +]) > + > +AC_DEFUN([AC_CHECK_SFBPF], > +[ > + AC_ARG_WITH(libsfbpf_includes, > + [ --with-libsfbpf-includes=DIR libsfbpf include > directory], > + [with_sfbpf_includes="$withval"], > [with_sfbpf_includes="no"]) > + > + AC_ARG_WITH(libsfbpf_libraries, > + [ --with-libsfbpf-libraries=DIR libsfbpf > library directory], > + [with_sfbpf_libraries="$withval"], > [with_sfbpf_libraries="no"]) > + > + if test "x$with_sfbpf_includes" != "xno"; then > + CPPFLAGS="${CPPFLAGS} -I${with_sfbpf_includes}" > + fi > + > + if test "x$with_sfbpf_libraries" != "xno"; then > + LDFLAGS="${LDFLAGS} -L${with_sfbpf_libraries}" > + fi > + > + AC_CHECK_HEADER([sfbpf.h], [], [AC_MSG_ERROR([Could not find > sfbpf.h!])]) > + AC_CHECK_LIB([sfbpf], [sfbpf_compile], [], > [AC_MSG_ERROR([Could not link against the SFBPF library!])]) > +]) > + > -- > 1.8.5.1.163.gd7aced9 > > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org> > http://lists.linaro.org/mailman/listinfo/lng-odp > > > > > -- > *Mike Holmes* > Linaro Technical Manager / Lead > LNG - ODP
diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..441ba51 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +Copyright (c) 2013-2014, Linaro Limited +All rights reserved. + +SPDX-License-Identifier: BSD-3-Clause + +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 Linaro Limited 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 HOLDER 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. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..93c5cdf --- /dev/null +++ b/Makefile.am @@ -0,0 +1,8 @@ +AUTOMAKE_OPTIONS = foreign + +ACLOCAL_AMFLAGS = -I m4 + +pkglib_LTLIBRARIES = daq_odp.la +daq_example_la_SOURCES = daq_odp.c +daq_example_la_CFLAGS = -DBUILDING_SO +daq_example_la_LDFLAGS = -module -export-dynamic -avoid-version -shared diff --git a/README b/README new file mode 100644 index 0000000..eec4f87 --- /dev/null +++ b/README @@ -0,0 +1,9 @@ +OpenDataPlane (http://opendataplane.org, ODP) is open source (BSD-license) +framework to support networking on different platforms and architectures. +Current daq module implements odp functionality to listen for +traffic on hardware optimized NICs. + +How to build: + autoreconf -ivf + ./configure + make diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..425caca --- /dev/null +++ b/configure.ac @@ -0,0 +1,43 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.62) +AC_INIT([odp-daq-module], [0.1], [maxim.uvarov@linaro.org]) +AM_INIT_AUTOMAKE([daq], [0.1]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_SRCDIR([daq_odp.c]) +AC_CONFIG_HEADERS([config.h]) + +# Checks for programs. +AC_PROG_CC +AC_PROG_LIBTOOL + +# Enable visibility if we can +AC_ENABLE_VISIBILITY() +# Special compiler flags for ICC, etc. +AC_SF_COMPILER_SETUP() + +# Checks for the DAQ API headers and the SFBPF headers/library. +AC_CHECK_DAQ_API +AC_CHECK_SFBPF + +# Checks for other dependencies of your DAQ module go here. + + +# Checks for header files. +AC_CHECK_HEADERS([netinet/in.h stdint.h stdlib.h string.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_TYPE_SIZE_T +AC_TYPE_UINT32_T +AC_TYPE_UINT8_T + +# Checks for library functions. +AC_FUNC_MALLOC +AC_CHECK_FUNCS([memset strchr strdup strerror strtol]) + +# Substitutions + +# Output +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/daq_odp.c b/daq_odp.c new file mode 100644 index 0000000..c7983bc --- /dev/null +++ b/daq_odp.c @@ -0,0 +1,394 @@ +/* + ** Copyright (c) 2014, Linaro Limited + ** All rights reserved. + ** + ** SPDX-License-Identifier: BSD-3-Clause + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <linux/if_ether.h> +#include <linux/if_packet.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <netinet/in.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/poll.h> +#include <sys/socket.h> +#include <unistd.h> + +#include "daq_api.h" +#include "sfbpf.h" + +#include <odp.h> +#include <helper/odp_linux.h> +#include <helper/odp_packet_helper.h> +#include <helper/odp_eth.h> +#include <helper/odp_ip.h> + +#define MAX_WORKERS 1 +#define SHM_PKT_POOL_SIZE (512*2048) +#define SHM_PKT_POOL_BUF_SIZE 1856 +#define MAX_PKT_BURST 16 +#define ODP_DEBUG 1 + +typedef struct _odp_context +{ + volatile int break_loop; + DAQ_Stats_t stats; + DAQ_State state; + odp_queue_t inq_def; + odp_pktio_t pktio; + int snaplen; + char *device; + char errbuf[256]; +} ODP_Context_t; + +static int odp_daq_initialize(const DAQ_Config_t *config, void **ctxt_ptr, char *errbuf, size_t errlen) +{ + ODP_Context_t *odpc; + int rval = DAQ_ERROR; + int thr_id; + odp_buffer_pool_t pool; + odp_pktio_params_t params; + socket_params_t *sock_params = ¶ms.sock_params; + odp_queue_param_t qparam; + char inq_name[ODP_QUEUE_NAME_LEN]; + int ret; + void *pool_base; + + rval = DAQ_ERROR; + + odpc = calloc(1, sizeof(ODP_Context_t)); + if (!odpc) + { + snprintf(errbuf, errlen, "%s: Couldn't allocate memory for the new ODP context!", __FUNCTION__); + rval = DAQ_ERROR_NOMEM; + goto err; + } + + odpc->device = strdup(config->name); + if (!odpc->device) + { + snprintf(errbuf, errlen, "%s: Couldn't allocate memory for the device string!", __FUNCTION__); + rval = DAQ_ERROR_NOMEM; + goto err; + } + + *ctxt_ptr = odpc; + + /* Init ODP before calling anything else */ + if (odp_init_global()) { + ODP_ERR("Error: ODP global init failed.\n"); + goto err; + } + + /* Init this thread */ + thr_id = odp_thread_create(0); + odp_init_local(thr_id); + + /* Create packet pool */ + pool_base = odp_shm_reserve("shm_packet_pool", + SHM_PKT_POOL_SIZE, ODP_CACHE_LINE_SIZE); + if (pool_base == NULL) { + ODP_ERR("Error: packet pool mem alloc failed.\n"); + rval = DAQ_ERROR_NOMEM; + goto err; + } + + pool = odp_buffer_pool_create("packet_pool", pool_base, + SHM_PKT_POOL_SIZE, + SHM_PKT_POOL_BUF_SIZE, + ODP_CACHE_LINE_SIZE, + ODP_BUFFER_TYPE_PACKET); + if (pool == ODP_BUFFER_POOL_INVALID) { + ODP_ERR("Error: packet pool create failed.\n"); + rval = DAQ_ERROR; + goto err; + } + odpc->snaplen = SHM_PKT_POOL_BUF_SIZE; + odp_buffer_pool_print(pool); + + /* Open a packet IO instance for this thread */ + sock_params->type = ODP_PKTIO_TYPE_SOCKET_MMAP; + sock_params->fanout = 0; + + odpc->pktio = odp_pktio_open(odpc->device, pool, ¶ms); + if (odpc->pktio == ODP_PKTIO_INVALID) { + ODP_ERR(" [%02i] Error: pktio create failed\n", 1 /*thr*/); + rval = DAQ_ERROR_NODEV; + goto err; + } + + /* + * Create and set the default INPUT queue associated with the 'pktio' + * resource + */ + qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; + qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; + qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; + snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)odpc->pktio); + inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; + + odpc->inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam); + if (odpc->inq_def == ODP_QUEUE_INVALID) { + ODP_ERR(" [%02i] Error: pktio queue creation failed\n", 1 /*thr*/); + goto err; + } + + ret = odp_pktio_inq_setdef(odpc->pktio, odpc->inq_def); + if (ret != 0) { + ODP_ERR(" [%02i] Error: default input-Q setup\n", 1 /*thr*/); + goto err; + } + + odpc->state = DAQ_STATE_INITIALIZED; + + printf("%s() DAQ_SUCCESS.\n\n", __func__); + return DAQ_SUCCESS; +err: + + return rval; +} + +static int odp_daq_set_filter(void *handle, const char *filter) +{ + /* not implemented yet */ + return DAQ_SUCCESS; +} + +static int odp_daq_start(void *handle) +{ + ODP_Context_t *odpc = (ODP_Context_t *) handle; + if (!odpc) + return DAQ_ERROR_NOCTX; + + odpc->state = DAQ_STATE_STARTED; + return DAQ_SUCCESS; +} + +static const DAQ_Verdict verdict_translation_table[MAX_DAQ_VERDICT] = { + DAQ_VERDICT_PASS, /* DAQ_VERDICT_PASS */ + DAQ_VERDICT_BLOCK, /* DAQ_VERDICT_BLOCK */ + DAQ_VERDICT_PASS, /* DAQ_VERDICT_REPLACE */ + DAQ_VERDICT_PASS, /* DAQ_VERDICT_WHITELIST */ + DAQ_VERDICT_BLOCK, /* DAQ_VERDICT_BLACKLIST */ + DAQ_VERDICT_PASS /* DAQ_VERDICT_IGNORE */ +}; + +static int odp_daq_acquire(void *handle, int cnt, DAQ_Analysis_Func_t callback, DAQ_Meta_Func_t metaback, void *user) +{ + ODP_Context_t *odpc; + DAQ_PktHdr_t daqhdr; + DAQ_Verdict verdict; + const uint8_t *data; + odp_packet_t pkt; + int i; + odp_packet_t pkt_tbl[MAX_PKT_BURST]; + int pkts; + + odpc = (ODP_Context_t *) handle; + if (!odpc) + return DAQ_ERROR; + + if (odpc->state != DAQ_STATE_STARTED) + return DAQ_ERROR; + + while (1) + { + /* Has breakloop() been called? */ + if (odpc->break_loop) + { + odpc->break_loop = 0; + return 0; + } + + pkts = odp_pktio_recv(odpc->pktio, pkt_tbl, MAX_PKT_BURST); + if (pkts <= 0) { + return 0; + } + + for (i = 0; i < pkts; ++i) { + pkt = pkt_tbl[i]; + + data = odp_packet_l2(pkt); + if (!data) { + //printf("no l2 offset, packet dropped\n"); + odpc->stats.packets_filtered++; + odp_buffer_free(pkt); + continue; + } + + verdict = DAQ_VERDICT_PASS; + + gettimeofday(&daqhdr.ts, NULL); + daqhdr.caplen = odp_buffer_size(pkt); + + daqhdr.pktlen = odp_packet_get_len(pkt); + daqhdr.ingress_index = 0; + daqhdr.egress_index = DAQ_PKTHDR_UNKNOWN; + daqhdr.ingress_group = DAQ_PKTHDR_UNKNOWN; + daqhdr.egress_group = DAQ_PKTHDR_UNKNOWN; + daqhdr.flags = 0; + daqhdr.opaque = 0; + daqhdr.priv_ptr = NULL; + daqhdr.address_space_id = 0; + + if (callback) + { + verdict = callback(user, &daqhdr, data); + if (verdict >= MAX_DAQ_VERDICT) + verdict = DAQ_VERDICT_PASS; + odpc->stats.verdicts[verdict]++; + verdict = verdict_translation_table[verdict]; + } + + odp_buffer_free(pkt); + } + + if (pkts > 0) { + odpc->stats.packets_received += pkts; + break; + } + } + return 0; +} + +static int odp_daq_inject(void *handle, const DAQ_PktHdr_t *hdr, const uint8_t *packet_data, uint32_t len, int reverse) +{ + return DAQ_SUCCESS; +} + +static int odp_daq_breakloop(void *handle) +{ + ODP_Context_t *odpc = (ODP_Context_t *) handle; + + odpc->break_loop = 1; + return DAQ_SUCCESS; +} + +static int odp_daq_stop(void *handle) +{ + ODP_Context_t *odpc = (ODP_Context_t *) handle; + + odpc->break_loop = 1; + odp_timer_disarm_all(); + odpc->state = DAQ_STATE_STOPPED; + + return DAQ_SUCCESS; +} + +static void odp_daq_shutdown(void *handle) +{ + odp_timer_disarm_all(); +} + +static DAQ_State odp_daq_check_status(void *handle) +{ + ODP_Context_t *odpc = (ODP_Context_t *) handle; + + if (!odpc) { + return DAQ_STATE_UNINITIALIZED; + } + + return odpc->state; +} + +static int odp_daq_get_stats(void *handle, DAQ_Stats_t *stats) +{ + ODP_Context_t *odpc = (ODP_Context_t *) handle; + + memcpy(stats, &odpc->stats, sizeof(DAQ_Stats_t)); + return DAQ_SUCCESS; +} + +static void odp_daq_reset_stats(void *handle) +{ + ODP_Context_t *odpc = (ODP_Context_t *) handle; + + memset(&odpc->stats, 0, sizeof(DAQ_Stats_t)); +} + +static int odp_daq_get_snaplen(void *handle) +{ + ODP_Context_t *odpc = (ODP_Context_t *) handle; + + if (odpc) + return odpc->snaplen; + + return 1500; +} + +static uint32_t odp_daq_get_capabilities(void *handle) +{ + return DAQ_CAPA_BLOCK | DAQ_CAPA_REPLACE | DAQ_CAPA_BREAKLOOP | DAQ_CAPA_DEVICE_INDEX; +} + +static int odp_daq_get_datalink_type(void *handle) +{ + return DLT_EN10MB; +} + +static const char *odp_daq_get_errbuf(void *handle) +{ + ODP_Context_t *odpc = (ODP_Context_t *) handle; + + return odpc->errbuf; +} + +static void odp_daq_set_errbuf(void *handle, const char *string) +{ + ODP_Context_t *odpc = (ODP_Context_t *) handle; + + if (!string) + return; + + DPE(odpc->errbuf, "%s", string); + return; +} + +static int odp_daq_get_device_index(void *handle, const char *string) +{ + return DAQ_ERROR_NOTSUP; +} + +#ifdef BUILDING_SO +DAQ_SO_PUBLIC const DAQ_Module_t DAQ_MODULE_DATA = +#else +const DAQ_Module_t afpacket_daq_module_data = +#endif +{ + .api_version = DAQ_API_VERSION, + .module_version = 1, + .name = "odp", + .type = DAQ_TYPE_INTF_CAPABLE | DAQ_TYPE_INLINE_CAPABLE | DAQ_TYPE_MULTI_INSTANCE, + .initialize = odp_daq_initialize, + .set_filter = odp_daq_set_filter, + .start = odp_daq_start, + .acquire = odp_daq_acquire, + .inject = odp_daq_inject, + .breakloop = odp_daq_breakloop, + .stop = odp_daq_stop, + .shutdown = odp_daq_shutdown, + .check_status = odp_daq_check_status, + .get_stats = odp_daq_get_stats, + .reset_stats = odp_daq_reset_stats, + .get_snaplen = odp_daq_get_snaplen, + .get_capabilities = odp_daq_get_capabilities, + .get_datalink_type = odp_daq_get_datalink_type, + .get_errbuf = odp_daq_get_errbuf, + .set_errbuf = odp_daq_set_errbuf, + .get_device_index = odp_daq_get_device_index, + .modify_flow = NULL, + .hup_prep = NULL, + .hup_apply = NULL, + .hup_post = NULL, +}; diff --git a/m4/ax_cflags_gcc_option.m4 b/m4/ax_cflags_gcc_option.m4 new file mode 100644 index 0000000..22e6b53 --- /dev/null +++ b/m4/ax_cflags_gcc_option.m4 @@ -0,0 +1,221 @@ +# =========================================================================== +# http://www.nongnu.org/autoconf-archive/ax_cflags_gcc_option.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CFLAGS_GCC_OPTION (optionflag [,[shellvar][,[A][,[NA]]]) +# +# DESCRIPTION +# +# AX_CFLAGS_GCC_OPTION(-fvomit-frame) would show a message as like +# "checking CFLAGS for gcc -fvomit-frame ... yes" and adds the optionflag +# to CFLAGS if it is understood. You can override the shellvar-default of +# CFLAGS of course. The order of arguments stems from the explicit macros +# like AX_CFLAGS_WARN_ALL. +# +# The cousin AX_CXXFLAGS_GCC_OPTION would check for an option to add to +# CXXFLAGS - and it uses the autoconf setup for C++ instead of C (since it +# is possible to use different compilers for C and C++). +# +# The macro is a lot simpler than any special AX_CFLAGS_* macro (or +# ax_cxx_rtti.m4 macro) but allows to check for arbitrary options. +# However, if you use this macro in a few places, it would be great if you +# would make up a new function-macro and submit it to the ac-archive. +# +# - $1 option-to-check-for : required ("-option" as non-value) +# - $2 shell-variable-to-add-to : CFLAGS (or CXXFLAGS in the other case) +# - $3 action-if-found : add value to shellvariable +# - $4 action-if-not-found : nothing +# +# Note: in earlier versions, $1-$2 were swapped. We try to detect the +# situation and accept a $2=~/-/ as being the old option-to-check-for. +# +# There are other variants that emerged from the original macro variant +# which did just test an option to be possibly added. However, some +# compilers accept an option silently, or possibly for just another option +# that was not intended. Therefore, we have to do a generic test for a +# compiler family. For gcc we check "-pedantic" being accepted which is +# also understood by compilers who just want to be compatible with gcc +# even when not being made from gcc sources. +# +# See also: AX_CFLAGS_SUN_OPTION, AX_CFLAGS_HPUX_OPTION, +# AX_CFLAGS_AIX_OPTION, and AX_CFLAGS_IRIX_OPTION. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 7 + +AC_DEFUN([AX_CFLAGS_GCC_OPTION_OLD], [dnl +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ax_cv_cflags_gcc_option_$2])dnl +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_C + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC + "-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + + +dnl the only difference - the LANG selection... and the default FLAGS + +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_OLD], [dnl +AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ax_cv_cxxflags_gcc_option_$2])dnl +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC + "-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + +dnl ------------------------------------------------------------------------- + +AC_DEFUN([AX_CFLAGS_GCC_OPTION_NEW], [dnl +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ax_cv_cflags_gcc_option_[]m4_translit([[$1]],[=],[_])])dnl +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_C + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC + "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + + +dnl the only difference - the LANG selection... and the default FLAGS + +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_NEW], [dnl +AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ax_cv_cxxflags_gcc_option_$1])dnl +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC + "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + +AC_DEFUN([AX_CFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, +[AX_CFLAGS_GCC_OPTION_NEW($@)],[AX_CFLAGS_GCC_OPTION_OLD($@)])]) + +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, +[AX_CXXFLAGS_GCC_OPTION_NEW($@)],[AX_CXXFLAGS_GCC_OPTION_OLD($@)])]) diff --git a/m4/sf.m4 b/m4/sf.m4 new file mode 100644 index 0000000..547a993 --- /dev/null +++ b/m4/sf.m4 @@ -0,0 +1,198 @@ +dnl Enable visibility if we can +dnl modified from gnulib/m4/visibility.m4 +AC_DEFUN([AC_ENABLE_VISIBILITY], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_MSG_CHECKING([for visibility support]) + AC_CACHE_VAL(gl_cv_cc_visibility, [ + gl_save_CFLAGS="$CFLAGS" + # Add -Werror flag since some compilers, e.g. icc 7.1, don't support it, + # but only warn about it instead of compilation failing + CFLAGS="$CFLAGS -Werror -fvisibility=hidden" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void);]], + [[]])], + [gl_cv_cc_visibility="yes"], + [gl_cv_cc_visibility="no"]) + ]) + AC_MSG_RESULT([$gl_cv_cc_visibility]) + if test "x$gl_cv_cc_visibility" = "xyes"; then + CFLAGS="$gl_save_CFLAGS -fvisibility=hidden" + AC_DEFINE([HAVE_VISIBILITY],[1], + [Define if the compiler supports visibility declarations.]) + else + CFLAGS="$gl_save_CFLAGS" + fi +]) + +dnl Special compiler flags for ICC +dnl GCC strict CFLAGS +AC_DEFUN([AC_SF_COMPILER_SETUP], + [AC_REQUIRE([AC_PROG_CC]) + ICC=no + if eval "echo $CC | grep icc > /dev/null" ; then + if eval "$CC -help | grep libcxa > /dev/null" ; then + CFLAGS="$CFLAGS -static-libcxa" + LDFLAGS="$LDFLAGS -static-libcxa" + XCCFLAGS="-XCClinker -static-libcxa" + else + CFLAGS="$CFLAGS -static-intel" + LDFLAGS="$LDFLAGS -static-intel" + XCCFLAGS="-XCClinker -static-intel" + fi + CFLAGS=`echo $CFLAGS | sed 's/-O2/-O3/'` + CFLAGS="$CFLAGS -ip -w1" + ICC=yes + GCC=no + fi + + if test "$GCC" = yes ; then + AX_CFLAGS_GCC_OPTION(-Wall) + AX_CFLAGS_GCC_OPTION(-Wwrite-strings) + AX_CFLAGS_GCC_OPTION(-Wsign-compare) + AX_CFLAGS_GCC_OPTION(-Wcast-align) + AX_CFLAGS_GCC_OPTION(-Wextra) + AX_CFLAGS_GCC_OPTION(-Wformat) + AX_CFLAGS_GCC_OPTION(-Wformat-security) + AX_CFLAGS_GCC_OPTION(-Wno-unused-parameter) + AX_CFLAGS_GCC_OPTION(-fno-strict-aliasing) + AX_CFLAGS_GCC_OPTION(-fdiagnostics-show-option) + AX_CFLAGS_GCC_OPTION(-pedantic -std=c99 -D_GNU_SOURCE) + fi +]) + +dnl +dnl Check for flex, default to lex +dnl Require flex 2.4 or higher +dnl Check for bison, default to yacc +dnl Default to lex/yacc if both flex and bison are not available +dnl Define the yy prefix string if using flex and bison +dnl +dnl usage: +dnl +dnl AC_LBL_LEX_AND_YACC(lex, yacc, yyprefix) +dnl +dnl results: +dnl +dnl $1 (lex set) +dnl $2 (yacc appended) +dnl $3 (optional flex and bison -P prefix) +dnl +AC_DEFUN([AC_LBL_LEX_AND_YACC], + [AC_ARG_WITH(flex, [ --without-flex don't use flex]) + AC_ARG_WITH(bison, [ --without-bison don't use bison]) + if test "$with_flex" = no ; then + $1=lex + else + AC_CHECK_PROGS($1, flex, lex) + fi + if test "$$1" = flex ; then + # The -V flag was added in 2.4 + AC_MSG_CHECKING(for flex 2.4 or higher) + AC_CACHE_VAL(ac_cv_lbl_flex_v24, + if flex -V >/dev/null 2>&1; then + ac_cv_lbl_flex_v24=yes + else + ac_cv_lbl_flex_v24=no + fi) + AC_MSG_RESULT($ac_cv_lbl_flex_v24) + if test $ac_cv_lbl_flex_v24 = no ; then + s="2.4 or higher required" + AC_MSG_WARN(ignoring obsolete flex executable ($s)) + $1=lex + fi + fi + if test "$with_bison" = no ; then + $2=yacc + else + AC_CHECK_PROGS($2, bison, yacc) + fi + if test "$$2" = bison ; then + $2="$$2 -y" + fi + if test "$$1" != lex -a "$$2" = yacc -o "$$1" = lex -a "$$2" != yacc ; then + AC_MSG_WARN(don't have both flex and bison; reverting to lex/yacc) + $1=lex + $2=yacc + fi + if test "$$1" = flex -a -n "$3" ; then + $1="$$1 -P$3" + $2="$$2 -p $3" + fi]) + +AC_DEFUN([AC_CHECK_PCAP_VER], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_MSG_CHECKING([for pcap_lib_version]) + AC_CHECK_LIB([pcap],[pcap_lib_version],[LIBS="-lpcap ${LIBS}"],[have_pcap_lib_version="no"],[]) + if test "x$have_pcap_lib_version" = "xno"; then + echo + echo " ERROR! Libpcap library version >= $1 not found." + echo " Get it from http://www.tcpdump.org" + echo + exit 1 + fi + AC_MSG_CHECKING([for libpcap version >= $1]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[ + #include <pcap.h> + #include <string.h> + extern char pcap_version[]; + ]], + [[ + if (strcmp(pcap_version, $1) < 0) + return 1; + ]])], + [libpcap_version_1x="yes"], + [libpcap_version_1x="no"]) + if test "x$libpcap_version_1x" = "xno"; then + AC_MSG_RESULT(no) + echo + echo " ERROR! Libpcap library version >= $1 not found." + echo " Get it from http://www.tcpdump.org" + echo + exit 1 + else + AC_MSG_RESULT(yes) + fi +]) + +AC_DEFUN([AC_CHECK_DAQ_API], +[ + AC_ARG_WITH(libdaq_includes, + [ --with-libdaq-includes=DIR libdaq include directory], + [with_daq_includes="$withval"], [with_daq_includes="no"]) + + if test "x$with_daq_includes" != "xno"; then + CPPFLAGS="${CPPFLAGS} -I${with_daq_includes}" + fi + + AC_CHECK_HEADER([daq_api.h], [], [AC_MSG_ERROR([Could not find daq_api.h!])]) +]) + +AC_DEFUN([AC_CHECK_SFBPF], +[ + AC_ARG_WITH(libsfbpf_includes, + [ --with-libsfbpf-includes=DIR libsfbpf include directory], + [with_sfbpf_includes="$withval"], [with_sfbpf_includes="no"]) + + AC_ARG_WITH(libsfbpf_libraries, + [ --with-libsfbpf-libraries=DIR libsfbpf library directory], + [with_sfbpf_libraries="$withval"], [with_sfbpf_libraries="no"]) + + if test "x$with_sfbpf_includes" != "xno"; then + CPPFLAGS="${CPPFLAGS} -I${with_sfbpf_includes}" + fi + + if test "x$with_sfbpf_libraries" != "xno"; then + LDFLAGS="${LDFLAGS} -L${with_sfbpf_libraries}" + fi + + AC_CHECK_HEADER([sfbpf.h], [], [AC_MSG_ERROR([Could not find sfbpf.h!])]) + AC_CHECK_LIB([sfbpf], [sfbpf_compile], [], [AC_MSG_ERROR([Could not link against the SFBPF library!])]) +]) +
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> --- Hello, This is ODP Snort/DAQ module. The propose of this change is to publish it on github as separate project. Sending to our mailing list for review/testing. Anders, please check if we need something more odp specific to m4 scripts. I did compilation check and stress test blasting pcap to that module. Thank you, Maxim. LICENSE | 29 ++++ Makefile.am | 8 + README | 9 ++ configure.ac | 43 +++++ daq_odp.c | 394 +++++++++++++++++++++++++++++++++++++++++++++ m4/ax_cflags_gcc_option.m4 | 221 +++++++++++++++++++++++++ m4/sf.m4 | 198 +++++++++++++++++++++++ 7 files changed, 902 insertions(+) create mode 100644 LICENSE create mode 100644 Makefile.am create mode 100644 README create mode 100644 configure.ac create mode 100644 daq_odp.c create mode 100644 m4/ax_cflags_gcc_option.m4 create mode 100644 m4/sf.m4