Message ID | 1407159964-14731-1-git-send-email-maxim.uvarov@linaro.org |
---|---|
State | New |
Headers | show |
mike@fedora1:~/git/odp-apps$ git am ~/incoming/lng-odp_APPS_PATCHv2_ODP_daq_module_initial_version.mbox Applying: ODP daq module initial version. /home/mike/git/odp-apps/.git/rebase-apply/patch:49: new blank line at EOF. + /home/mike/git/odp-apps/.git/rebase-apply/patch:994: new blank line at EOF. + warning: 2 lines add whitespace errors. On 4 August 2014 09:46, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> > --- > v2: - fix configure.ac to proper build; > - added .gitignore > - added check for odp.h > > .gitignore | 20 +++ > LICENSE | 29 ++++ > Makefile.am | 8 + > README | 9 ++ > configure.ac | 44 +++++ > daq_odp.c | 394 > +++++++++++++++++++++++++++++++++++++++++++++ > m4/ax_cflags_gcc_option.m4 | 221 +++++++++++++++++++++++++ > m4/sf.m4 | 198 +++++++++++++++++++++++ > 8 files changed, 923 insertions(+) > create mode 100644 .gitignore > 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/.gitignore b/.gitignore > new file mode 100644 > index 0000000..a600efa > --- /dev/null > +++ b/.gitignore > @@ -0,0 +1,20 @@ > +*.m4 > +*.lo > +*.o > +*.swp > +.deps/ > +.gitignore > +.libs/ > +Makefile > +Makefile.in > +autom4te.cache/ > +config.* > +configure > +*.la > +depcomp > +install-sh > +libtool > +ltmain.sh > +missing > +stamp-h1 > + > 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..6e949b8 > --- /dev/null > +++ b/Makefile.am > @@ -0,0 +1,8 @@ > +AUTOMAKE_OPTIONS = foreign > + > +ACLOCAL_AMFLAGS = -I m4 > + > +pkglib_LTLIBRARIES = daq_odp.la > +daq_odp_la_SOURCES = daq_odp.c > +daq_odp_la_CFLAGS = -DBUILDING_SO > +daq_odp_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..7ab51ab > --- /dev/null > +++ b/configure.ac > @@ -0,0 +1,44 @@ > +# > -*- 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 odp.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]) > +AC_SEARCH_LIBS([timer_createm],[rt posix4]) > + > +# 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 >
OK, will fix before apply. Maxim. On 08/05/2014 06:33 PM, Mike Holmes wrote: > mike@fedora1:~/git/odp-apps$ git am > ~/incoming/lng-odp_APPS_PATCHv2_ODP_daq_module_initial_version.mbox > Applying: ODP daq module initial version. > /home/mike/git/odp-apps/.git/rebase-apply/patch:49: new blank line at EOF. > + > /home/mike/git/odp-apps/.git/rebase-apply/patch:994: new blank line at > EOF. > + > warning: 2 lines add whitespace errors. > > > > On 4 August 2014 09:46, 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>> > --- > v2: - fix configure.ac <http://configure.ac> to proper build; > - added .gitignore > - added check for odp.h > > .gitignore | 20 +++ > LICENSE | 29 ++++ > Makefile.am | 8 + > README | 9 ++ > configure.ac <http://configure.ac> | 44 +++++ > daq_odp.c | 394 > +++++++++++++++++++++++++++++++++++++++++++++ > m4/ax_cflags_gcc_option.m4 | 221 +++++++++++++++++++++++++ > m4/sf.m4 | 198 +++++++++++++++++++++++ > 8 files changed, 923 insertions(+) > create mode 100644 .gitignore > 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/.gitignore b/.gitignore > new file mode 100644 > index 0000000..a600efa > --- /dev/null > +++ b/.gitignore > @@ -0,0 +1,20 @@ > +*.m4 > +*.lo > +*.o > +*.swp > +.deps/ > +.gitignore > +.libs/ > +Makefile > +Makefile.in > +autom4te.cache/ > +config.* > +configure > +*.la > +depcomp > +install-sh > +libtool > +ltmain.sh > +missing > +stamp-h1 > + > 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..6e949b8 > --- /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_odp_la_SOURCES = daq_odp.c > +daq_odp_la_CFLAGS = -DBUILDING_SO > +daq_odp_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..7ab51ab > --- /dev/null > +++ b/configure.ac <http://configure.ac> > @@ -0,0 +1,44 @@ > +# -*- 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 odp.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]) > +AC_SEARCH_LIBS([timer_createm],[rt posix4]) > + > +# 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
I found a couple more things that might matter. README should probably say you need to install libdaq-dev I think ./configure should take an argument to point to the installed ODP as it is likely to not be in the regular include path (cross compile), maybe something like . ./configure --odp_path=<your path> On 5 August 2014 10:37, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > OK, will fix before apply. > > Maxim. > > > On 08/05/2014 06:33 PM, Mike Holmes wrote: > >> mike@fedora1:~/git/odp-apps$ git am ~/incoming/lng-odp_APPS_ >> PATCHv2_ODP_daq_module_initial_version.mbox >> Applying: ODP daq module initial version. >> /home/mike/git/odp-apps/.git/rebase-apply/patch:49: new blank line at >> EOF. >> + >> /home/mike/git/odp-apps/.git/rebase-apply/patch:994: new blank line at >> EOF. >> + >> warning: 2 lines add whitespace errors. >> >> >> >> On 4 August 2014 09:46, 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>> >> --- >> v2: - fix configure.ac <http://configure.ac> to proper build; >> >> - added .gitignore >> - added check for odp.h >> >> .gitignore | 20 +++ >> LICENSE | 29 ++++ >> Makefile.am | 8 + >> README | 9 ++ >> configure.ac <http://configure.ac> | 44 +++++ >> >> daq_odp.c | 394 >> +++++++++++++++++++++++++++++++++++++++++++++ >> m4/ax_cflags_gcc_option.m4 | 221 +++++++++++++++++++++++++ >> m4/sf.m4 | 198 +++++++++++++++++++++++ >> 8 files changed, 923 insertions(+) >> create mode 100644 .gitignore >> 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/.gitignore b/.gitignore >> new file mode 100644 >> index 0000000..a600efa >> --- /dev/null >> +++ b/.gitignore >> @@ -0,0 +1,20 @@ >> +*.m4 >> +*.lo >> +*.o >> +*.swp >> +.deps/ >> +.gitignore >> +.libs/ >> +Makefile >> +Makefile.in >> +autom4te.cache/ >> +config.* >> +configure >> +*.la >> +depcomp >> +install-sh >> +libtool >> +ltmain.sh >> +missing >> +stamp-h1 >> + >> 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..6e949b8 >> --- /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_odp_la_SOURCES = daq_odp.c >> +daq_odp_la_CFLAGS = -DBUILDING_SO >> +daq_odp_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..7ab51ab >> --- /dev/null >> +++ b/configure.ac <http://configure.ac> >> >> @@ -0,0 +1,44 @@ >> +# -*- 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 odp.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]) >> +AC_SEARCH_LIBS([timer_createm],[rt posix4]) >> + >> +# 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 >> > >
On Mon, Aug 04, 2014 at 02:46:04PM +0100, Maxim Uvarov wrote: > Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> > --- > v2: - fix configure.ac to proper build; > - added .gitignore > - added check for odp.h > > .gitignore | 20 +++ > LICENSE | 29 ++++ > Makefile.am | 8 + > README | 9 ++ > configure.ac | 44 +++++ > daq_odp.c | 394 +++++++++++++++++++++++++++++++++++++++++++++ > m4/ax_cflags_gcc_option.m4 | 221 +++++++++++++++++++++++++ > m4/sf.m4 | 198 +++++++++++++++++++++++ > 8 files changed, 923 insertions(+) > create mode 100644 .gitignore > 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/Makefile.am b/Makefile.am > new file mode 100644 > index 0000000..6e949b8 > --- /dev/null > +++ b/Makefile.am > @@ -0,0 +1,8 @@ > +AUTOMAKE_OPTIONS = foreign > + > +ACLOCAL_AMFLAGS = -I m4 > + > +pkglib_LTLIBRARIES = daq_odp.la > +daq_odp_la_SOURCES = daq_odp.c > +daq_odp_la_CFLAGS = -DBUILDING_SO > +daq_odp_la_LDFLAGS = -module -export-dynamic -avoid-version -shared I needed to add this line to get it to find libodp.so correctly at runtime; daq_odp_la_LIBADD = -lodp [...] > +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); You're not taking into account the cnt parameter. > + 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; > +} > + [...] > + > +#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, This DAQ doesn't support INLINE as odp_daq_inject does nothing. Also it looks like it can't support MULTI_INSTANCE as calling odp_daq_initialise multiple times would not work (e.g. odp_buffer_pool_create would fail).
On 11 August 2014 19:12, Stuart Haslam <stuart.haslam@arm.com> wrote: > On Mon, Aug 04, 2014 at 02:46:04PM +0100, Maxim Uvarov wrote: > > Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> > > --- > > v2: - fix configure.ac to proper build; > > - added .gitignore > > - added check for odp.h > > > > .gitignore | 20 +++ > > LICENSE | 29 ++++ > > Makefile.am | 8 + > > README | 9 ++ > > configure.ac | 44 +++++ > > daq_odp.c | 394 > +++++++++++++++++++++++++++++++++++++++++++++ > > m4/ax_cflags_gcc_option.m4 | 221 +++++++++++++++++++++++++ > > m4/sf.m4 | 198 +++++++++++++++++++++++ > > 8 files changed, 923 insertions(+) > > create mode 100644 .gitignore > > 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/Makefile.am b/Makefile.am > > new file mode 100644 > > index 0000000..6e949b8 > > --- /dev/null > > +++ b/Makefile.am > > @@ -0,0 +1,8 @@ > > +AUTOMAKE_OPTIONS = foreign > > + > > +ACLOCAL_AMFLAGS = -I m4 > > + > > +pkglib_LTLIBRARIES = daq_odp.la > > +daq_odp_la_SOURCES = daq_odp.c > > +daq_odp_la_CFLAGS = -DBUILDING_SO > > +daq_odp_la_LDFLAGS = -module -export-dynamic -avoid-version -shared > > I needed to add this line to get it to find libodp.so correctly at > runtime; > > daq_odp_la_LIBADD = -lodp > > [...] > > thanks, added that. > > +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); > > You're not taking into account the cnt parameter. > > Yes, you talked about it previous time. In general cnt is always 0. So it's not really sufficient. And other modules do not take it in account also. Will recheck it one more time. > > + 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; > > +} > > + > > [...] > > > + > > +#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, > > This DAQ doesn't support INLINE as odp_daq_inject does nothing. > > Also it looks like it can't support MULTI_INSTANCE as calling > odp_daq_initialise > multiple times would not work (e.g. odp_buffer_pool_create would fail). > > Yes, I did not implement INLINE. For MULTI_INSTANCE I have thoughts with implementing ODP IPC, but will skip it for now. Thanks for review, Maxim. > -- > Stuart. > >
On Tue, Aug 12, 2014 at 09:11:54AM +0100, Maxim Uvarov wrote: > On 11 August 2014 19:12, Stuart Haslam <stuart.haslam@arm.com<mailto:stuart.haslam@arm.com>> wrote: > > On Mon, Aug 04, 2014 at 02:46:04PM +0100, Maxim Uvarov wrote: > > +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); >> >> You're not taking into account the cnt parameter. >> > > Yes, you talked about it previous time. In general cnt is always 0. So it's not really sufficient. > And other modules do not take it in account also. Will recheck it one more time. > I did make the same comment in the last review but it wasn't fixed and you didn't comment as to why you thought it wasn't needed so I assumed you'd just forgotten to fix it. Other DAQs do tend to obey the cnt, e.g. from daq_afpacket.c; while (c < cnt || cnt <= 0) { So cnt <= 0 means no limit. -- Stuart.
On 08/12/2014 12:46 PM, Stuart Haslam wrote: > On Tue, Aug 12, 2014 at 09:11:54AM +0100, Maxim Uvarov wrote: >> On 11 August 2014 19:12, Stuart Haslam <stuart.haslam@arm.com<mailto:stuart.haslam@arm.com>> wrote: >>> On Mon, Aug 04, 2014 at 02:46:04PM +0100, Maxim Uvarov wrote: >>> +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); >>> >>> You're not taking into account the cnt parameter. >>> >> Yes, you talked about it previous time. In general cnt is always 0. So it's not really sufficient. >> And other modules do not take it in account also. Will recheck it one more time. >> > I did make the same comment in the last review but it wasn't fixed and > you didn't comment as to why you thought it wasn't needed so I assumed > you'd just forgotten to fix it. Other DAQs do tend to obey the cnt, > e.g. from daq_afpacket.c; > > while (c < cnt || cnt <= 0) > { > > So cnt <= 0 means no limit. > > -- > Stuart. > Fixed. Did small test with snort .. -n 5 and ping -f from other lxc container. And snort quits after 5 packets. Please check here: https://github.com/muvarov/daq-odp Or do git pull. BR, Maxim.
On Tue, Aug 12, 2014 at 12:12:29PM +0100, Maxim Uvarov wrote: > On 08/12/2014 12:46 PM, Stuart Haslam wrote: > > On Tue, Aug 12, 2014 at 09:11:54AM +0100, Maxim Uvarov wrote: > >> On 11 August 2014 19:12, Stuart Haslam wrote: > >>> On Mon, Aug 04, 2014 at 02:46:04PM +0100, Maxim Uvarov wrote: > >>> +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); > >>> > >>> You're not taking into account the cnt parameter. > >>> > >> Yes, you talked about it previous time. In general cnt is always 0. So it's not really sufficient. > >> And other modules do not take it in account also. Will recheck it one more time. > >> > > I did make the same comment in the last review but it wasn't fixed and > > you didn't comment as to why you thought it wasn't needed so I assumed > > you'd just forgotten to fix it. Other DAQs do tend to obey the cnt, > > e.g. from daq_afpacket.c; > > > > while (c < cnt || cnt <= 0) > > { > > > > So cnt <= 0 means no limit. > > > > -- > > Stuart. > > > Fixed. Did small test with snort .. -n 5 and ping -f from other lxc > container. And snort quits after 5 packets. > Please check here: > https://github.com/muvarov/daq-odp > > Or do git pull. > > BR, > Maxim. > OK, looks fine to me now.
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a600efa --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +*.m4 +*.lo +*.o +*.swp +.deps/ +.gitignore +.libs/ +Makefile +Makefile.in +autom4te.cache/ +config.* +configure +*.la +depcomp +install-sh +libtool +ltmain.sh +missing +stamp-h1 + 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..6e949b8 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,8 @@ +AUTOMAKE_OPTIONS = foreign + +ACLOCAL_AMFLAGS = -I m4 + +pkglib_LTLIBRARIES = daq_odp.la +daq_odp_la_SOURCES = daq_odp.c +daq_odp_la_CFLAGS = -DBUILDING_SO +daq_odp_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..7ab51ab --- /dev/null +++ b/configure.ac @@ -0,0 +1,44 @@ +# -*- 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 odp.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]) +AC_SEARCH_LIBS([timer_createm],[rt posix4]) + +# 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> --- v2: - fix configure.ac to proper build; - added .gitignore - added check for odp.h .gitignore | 20 +++ LICENSE | 29 ++++ Makefile.am | 8 + README | 9 ++ configure.ac | 44 +++++ daq_odp.c | 394 +++++++++++++++++++++++++++++++++++++++++++++ m4/ax_cflags_gcc_option.m4 | 221 +++++++++++++++++++++++++ m4/sf.m4 | 198 +++++++++++++++++++++++ 8 files changed, 923 insertions(+) create mode 100644 .gitignore 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