From patchwork Thu Jul 31 14:01:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Uvarov X-Patchwork-Id: 34652 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pd0-f198.google.com (mail-pd0-f198.google.com [209.85.192.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 2A5F820792 for ; Thu, 31 Jul 2014 14:09:18 +0000 (UTC) Received: by mail-pd0-f198.google.com with SMTP id fp1sf16330827pdb.5 for ; Thu, 31 Jul 2014 07:09:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:subject :precedence:list-id:list-unsubscribe:list-archive:list-post :list-help:list-subscribe:mime-version:errors-to:sender :x-original-sender:x-original-authentication-results:mailing-list :content-type:content-transfer-encoding; bh=hnHSEL6E0EaSIV8veBnITqAme+3C7YW+E3s3UMfWcGk=; b=Bub/aCthCYPnlyd8jitLo5o5GMVRZw9zCvYEroHZ5+pAmXp+nUZwXZAzozTGsLmrpN DOCJAWVCBr8/sLSdgGXD4f8imBFZExwXfvXokKCkXsl/ljlfUnO9A0IUCCDRwg/sISPv RCdABOP48iFlKD3uSyM0eiKr7SEyjeJTKyLrO8IFI5jJ1g7LqKewUOZkrZ18dwHBNnuP 5nhllK13qRm+1Mp8sFTXGv0W7Fv4zoh1+rako5HyCUtpOXWuwaXI5fo/IERnefopPqvt DxsQpcdIb+W4WYhMsMIlhMobjEbHcXRys5sMaHtywJ7WLpVont0NfOLg6v6olzfFbwiD TXxA== X-Gm-Message-State: ALoCoQmSvPg7qr9jf+DhHRTkW0DcprPFftZjck8TG4hTrgpf4YZmVmmXrjGXIJ4mDjOggDwl4GMQ X-Received: by 10.66.218.162 with SMTP id ph2mr1720113pac.3.1406815757352; Thu, 31 Jul 2014 07:09:17 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.16.179 with SMTP id 48ls927751qgb.10.gmail; Thu, 31 Jul 2014 07:09:17 -0700 (PDT) X-Received: by 10.220.92.5 with SMTP id p5mr13044106vcm.7.1406815757090; Thu, 31 Jul 2014 07:09:17 -0700 (PDT) Received: from mail-vc0-f176.google.com (mail-vc0-f176.google.com [209.85.220.176]) by mx.google.com with ESMTPS id th6si4458433veb.55.2014.07.31.07.09.17 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 31 Jul 2014 07:09:17 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.176 as permitted sender) client-ip=209.85.220.176; Received: by mail-vc0-f176.google.com with SMTP id id10so4252154vcb.35 for ; Thu, 31 Jul 2014 07:09:17 -0700 (PDT) X-Received: by 10.52.248.146 with SMTP id ym18mr15150054vdc.8.1406815756822; Thu, 31 Jul 2014 07:09:16 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.37.5 with SMTP id tc5csp21214vcb; Thu, 31 Jul 2014 07:09:16 -0700 (PDT) X-Received: by 10.236.223.36 with SMTP id u34mr6864924yhp.79.1406815756129; Thu, 31 Jul 2014 07:09:16 -0700 (PDT) Received: from ip-10-141-164-156.ec2.internal (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTPS id y66si12515323yhc.184.2014.07.31.07.09.15 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 31 Jul 2014 07:09:16 -0700 (PDT) Received-SPF: none (google.com: lng-odp-bounces@lists.linaro.org does not designate permitted sender hosts) client-ip=54.225.227.206; Received: from localhost ([127.0.0.1] helo=ip-10-141-164-156.ec2.internal) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1XCr2h-00078k-3I; Thu, 31 Jul 2014 14:09:15 +0000 Received: from mail-la0-f51.google.com ([209.85.215.51]) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1XCr2T-00078E-J5 for lng-odp@lists.linaro.org; Thu, 31 Jul 2014 14:09:01 +0000 Received: by mail-la0-f51.google.com with SMTP id pn19so2115483lab.10 for ; Thu, 31 Jul 2014 07:08:55 -0700 (PDT) X-Received: by 10.112.25.104 with SMTP id b8mr11733217lbg.95.1406815301625; Thu, 31 Jul 2014 07:01:41 -0700 (PDT) Received: from localhost.localdomain (ppp91-76-29-79.pppoe.mtu-net.ru. [91.76.29.79]) by mx.google.com with ESMTPSA id kz1sm2126744lab.11.2014.07.31.07.01.17 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 31 Jul 2014 07:01:25 -0700 (PDT) From: Maxim Uvarov To: lng-odp@lists.linaro.org Date: Thu, 31 Jul 2014 18:01:10 +0400 Message-Id: <1406815270-13218-1-git-send-email-maxim.uvarov@linaro.org> X-Mailer: git-send-email 1.8.5.1.163.gd7aced9 X-Topics: patch Subject: [lng-odp] [PATCH] ODP daq module initial version. X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: lng-odp-bounces@lists.linaro.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: maxim.uvarov@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.176 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Signed-off-by: Maxim Uvarov --- Hello, This is ODP Snort/DAQ module. The propose of this change is to publish it on github as separate project. Sending to our mailing list for review/testing. Anders, please check if we need something more odp specific to m4 scripts. I did compilation check and stress test blasting pcap to that module. Thank you, Maxim. LICENSE | 29 ++++ Makefile.am | 8 + README | 9 ++ configure.ac | 43 +++++ daq_odp.c | 394 +++++++++++++++++++++++++++++++++++++++++++++ m4/ax_cflags_gcc_option.m4 | 221 +++++++++++++++++++++++++ m4/sf.m4 | 198 +++++++++++++++++++++++ 7 files changed, 902 insertions(+) create mode 100644 LICENSE create mode 100644 Makefile.am create mode 100644 README create mode 100644 configure.ac create mode 100644 daq_odp.c create mode 100644 m4/ax_cflags_gcc_option.m4 create mode 100644 m4/sf.m4 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..441ba51 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +Copyright (c) 2013-2014, Linaro Limited +All rights reserved. + +SPDX-License-Identifier: BSD-3-Clause + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +Neither the name of Linaro Limited nor the names of its contributors may be +used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..93c5cdf --- /dev/null +++ b/Makefile.am @@ -0,0 +1,8 @@ +AUTOMAKE_OPTIONS = foreign + +ACLOCAL_AMFLAGS = -I m4 + +pkglib_LTLIBRARIES = daq_odp.la +daq_example_la_SOURCES = daq_odp.c +daq_example_la_CFLAGS = -DBUILDING_SO +daq_example_la_LDFLAGS = -module -export-dynamic -avoid-version -shared diff --git a/README b/README new file mode 100644 index 0000000..eec4f87 --- /dev/null +++ b/README @@ -0,0 +1,9 @@ +OpenDataPlane (http://opendataplane.org, ODP) is open source (BSD-license) +framework to support networking on different platforms and architectures. +Current daq module implements odp functionality to listen for +traffic on hardware optimized NICs. + +How to build: + autoreconf -ivf + ./configure + make diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..425caca --- /dev/null +++ b/configure.ac @@ -0,0 +1,43 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.62) +AC_INIT([odp-daq-module], [0.1], [maxim.uvarov@linaro.org]) +AM_INIT_AUTOMAKE([daq], [0.1]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_SRCDIR([daq_odp.c]) +AC_CONFIG_HEADERS([config.h]) + +# Checks for programs. +AC_PROG_CC +AC_PROG_LIBTOOL + +# Enable visibility if we can +AC_ENABLE_VISIBILITY() +# Special compiler flags for ICC, etc. +AC_SF_COMPILER_SETUP() + +# Checks for the DAQ API headers and the SFBPF headers/library. +AC_CHECK_DAQ_API +AC_CHECK_SFBPF + +# Checks for other dependencies of your DAQ module go here. + + +# Checks for header files. +AC_CHECK_HEADERS([netinet/in.h stdint.h stdlib.h string.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_TYPE_SIZE_T +AC_TYPE_UINT32_T +AC_TYPE_UINT8_T + +# Checks for library functions. +AC_FUNC_MALLOC +AC_CHECK_FUNCS([memset strchr strdup strerror strtol]) + +# Substitutions + +# Output +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/daq_odp.c b/daq_odp.c new file mode 100644 index 0000000..c7983bc --- /dev/null +++ b/daq_odp.c @@ -0,0 +1,394 @@ +/* + ** Copyright (c) 2014, Linaro Limited + ** All rights reserved. + ** + ** SPDX-License-Identifier: BSD-3-Clause + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "daq_api.h" +#include "sfbpf.h" + +#include +#include +#include +#include +#include + +#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 +# +# 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 . +# +# 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 + #include + 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!])]) +]) +