From ddf995da3b7e96d70f9138f14e1910c4523ce843 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 25 Feb 2010 04:18:04 -0600 Subject: [PATCH] pfring support lb type, and now uses logging subsys --- configure.in | 15 +++++++++++-- src/source-pfring.c | 53 ++++++++++++++++++++++++++++++--------------- src/suricata.c | 10 ++++++++- src/util-error.c | 8 +++++++ src/util-error.h | 8 +++++++ suricata.yaml | 4 ++++ 6 files changed, 78 insertions(+), 20 deletions(-) diff --git a/configure.in b/configure.in index 506aceb1e3..d04f94a7cd 100644 --- a/configure.in +++ b/configure.in @@ -468,6 +468,8 @@ AC_INIT(configure.in) if test "$enable_pfring" = "yes"; then CFLAGS="$CFLAGS -DHAVE_PFRING" fi + +#We have to set CFLAGS for AC_TRY_COMPILE as it doesn't pay attention to CPPFLAGS AC_ARG_WITH(libpfring_includes, [ --with-libpfring-includes=DIR libpfring include directory], [with_libpfring_includes="$withval"],[with_libpfring_includes=no]) @@ -484,17 +486,26 @@ AC_INIT(configure.in) fi LIBPFRING="" - AC_CHECK_LIB(pfring, pfring_open,, LIBPFRING="no") + AC_CHECK_LIB(pfring, pfring_set_cluster,, LIBPFRING="no") if test "$LIBPFRING" = "no"; then if test "enable_pfring" = "yes"; then echo - echo " ERROR! --enable-pfring was passed but the library was not found, go get it" + echo " ERROR! --enable-pfring was passed but the library was not found or version is >4, go get it" echo " from http://www.ntop.org/PF_RING.html" echo exit 1 fi fi + AC_TRY_COMPILE([ #include ], + [ pfring *pd; pd = pfring_open("eth1", 1, 1515, 1); pfring_set_cluster(pd, 99, cluster_round_robin); ], + [ pfring_cluster_type_available=yes ], [:] + ) + if test "$pfring_cluster_type_available" = "yes"; then + CFLAGS="${CFLAGS} -DHAVE_PFRING_CLUSTER_TYPE" + fi + + # libpcap AC_ARG_WITH(libpcap_includes, [ --with-libpcap-includes=DIR libpcap include directory], diff --git a/src/source-pfring.c b/src/source-pfring.c index a440f8666b..4a3efdaafe 100644 --- a/src/source-pfring.c +++ b/src/source-pfring.c @@ -58,8 +58,8 @@ void TmModuleDecodePfringRegister (void) { */ TmEcode NoPfringSupportExit(ThreadVars *tv, void *initdata, void **data) { - printf("Error creating thread %s: you do not have support for pfring " - "enabled please recompile with --enable-pfring\n", tv->name); + SCLogError(SC_ERR_NO_PF_RING,"Error creating thread %s: you do not have support for pfring " + "enabled please recompile with --enable-pfring", tv->name); exit(EXIT_FAILURE); } @@ -75,11 +75,14 @@ typedef struct PfringThreadVars_ uint8_t cluster_id; char *interface; - + char *cluster_type; /* counters */ uint32_t pkts; uint64_t bytes; - //uint32_t errs; + +#ifdef HAVE_PFRING_CLUSTER_TYPE + cluster_type ctype; +#endif /* HAVE_PFRING_CLUSTER_TYPE */ ThreadVars *tv; } PfringThreadVars; @@ -169,7 +172,7 @@ TmEcode ReceivePfring(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) { int r; if (TmThreadsCheckFlag(tv, THV_KILL) || TmThreadsCheckFlag(tv, THV_PAUSE)) { - printf("ReceivePfring: interrupted.\n"); + SCLogInfo("interrupted."); return TM_ECODE_OK; } @@ -180,7 +183,7 @@ TmEcode ReceivePfring(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) { // hdr.parsed_pkt.ipv4_src,hdr.parsed_pkt.l4_src_port, hdr.parsed_pkt.ipv4_dst,hdr.parsed_pkt.l4_dst_port); PfringProcessPacket(ptv, &hdr, buffer,p); }else{ - printf("RecievePfring: pfring_recv error %" PRId32 "\n", r); + SCLogError(SC_ERR_PF_RING_RECV,"pfring_recv error %" PRId32 "", r); return TM_ECODE_FAILED; } @@ -205,6 +208,7 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) { int rc; u_int32_t version; char *tmpclusterid; + char *tmpctype; PfringThreadVars *ptv = SCMalloc(sizeof(PfringThreadVars)); if (ptv == NULL) { @@ -214,37 +218,52 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) { ptv->tv = tv; if (ConfGet("pfring.clusterid", &tmpclusterid) != 1){ - printf("could not get pfring.clusterid\n"); + SCLogError(SC_ERR_PF_RING_GET_CLUSTERID_FAILED,"could not get pfring.clusterid"); return TM_ECODE_FAILED; }else{ ptv->cluster_id = (uint8_t)atoi(tmpclusterid); - printf("ReceivePfringThreadInit: going to use clusterid %" PRId32 "\n", ptv->cluster_id); + SCLogInfo("Going to use clusterid %" PRId32 "", ptv->cluster_id); } if (ConfGet("pfring.interface", &ptv->interface) != 1){ - printf("ReceivePfringThreadInit: Could not get pfring.interface\n"); + SCLogError(SC_ERR_PF_RING_GET_INTERFACE_FAILED,"Could not get pfring.interface"); return TM_ECODE_FAILED; }else{ - printf("ReceivePfringThreadInit: going to use interface %s\n",ptv->interface); + SCLogInfo("going to use interface %s",ptv->interface); } ptv->pd = pfring_open(ptv->interface, LIBPFRING_PROMISC, LIBPFRING_SNAPLEN, LIBPFRING_REENTRANT); if(ptv->pd == NULL) { - printf("pfring_open error\n"); + SCLogError(SC_ERR_PF_RING_OPEN,"pfring_open error"); return TM_ECODE_FAILED; } else { pfring_set_application_name(ptv->pd, PROG_NAME); pfring_version(ptv->pd, &version); - printf("Using PF_RING v.%d.%d.%d\n", - (version & 0xFFFF0000) >> 16, - (version & 0x0000FF00) >> 8, - version & 0x000000FF); + SCLogInfo("Using PF_RING v.%d.%d.%d", + (version & 0xFFFF0000) >> 16, + (version & 0x0000FF00) >> 8, + version & 0x000000FF); } +#ifdef HAVE_PFRING_CLUSTER_TYPE + if (ConfGet("pfring.ctype", &tmpctype) != 1) { + SCLogError(SC_ERR_GET_CLUSTER_TYPE_FAILED,"Could not get pfring.ctype"); + return TM_ECODE_FAILED; + } else if (strncmp(tmpctype, "cluster_round_robin", 19) == 0 || strncmp(tmpctype, "cluster_flow", 12) == 0) { + SCLogInfo("pfring cluster type %s",tmpctype); + ptv->ctype = (cluster_type)tmpctype; + rc = pfring_set_cluster(ptv->pd, ptv->cluster_id, ptv->ctype); + } else { + SCLogError(SC_ERR_INVALID_CLUSTER_TYPE,"invalid hash type %s",tmpctype); + return TM_ECODE_FAILED; + } +#else rc = pfring_set_cluster(ptv->pd, ptv->cluster_id); +#endif /* HAVE_PFRING_CLUSTER_TYPE */ + if(rc != 0){ - printf("pfring_set_cluster returned %d\n", rc); + SCLogError(SC_ERR_PF_RING_SET_CLUSTER_FAILED,"pfring_set_cluster returned %d", rc); return TM_ECODE_FAILED; } @@ -338,7 +357,7 @@ TmEcode DecodePfringThreadInit(ThreadVars *tv, void *initdata, void **data) DecodeThreadVars *dtv = NULL; if ( (dtv = SCMalloc(sizeof(DecodeThreadVars))) == NULL) { - printf("Error Allocating memory\n"); + SCLogError(SC_ERR_MEM_ALLOC,"Error Allocating memory"); return TM_ECODE_FAILED; } memset(dtv, 0, sizeof(DecodeThreadVars)); diff --git a/src/suricata.c b/src/suricata.c index fdea746f50..591d42910d 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -374,7 +374,8 @@ void usage(const char *progname) printf("\t--init-errors-fatal : enable fatal failure on signature init error\n"); printf("\t--dump-config : show the running configuration\n"); printf("\t--pfring-int : run in pfring mode\n"); - printf("\t--pfring-clusterid : pfring cluster id to use for flow pinning\n"); + printf("\t--pfring-clusterid : pfring cluster id \n"); + printf("\t--pfring-ctype : pfring cluster type for PF_RING 4.1.2 and later cluster_round_robin|cluster_flow"); printf("\n"); printf("\nTo run the engine with default configuration on " "interface eth0 with signature file \"signatures.rules\", run the " @@ -419,6 +420,7 @@ int main(int argc, char **argv) {"dump-config", 0, &dump_config, 1}, {"pfring-int", required_argument, 0, 0}, {"pfring-clusterid", required_argument, 0, 0}, + {"pfring-ctype", required_argument, 0, 0}, {"unittest-filter", required_argument, 0, 'U'}, {"list-unittests", 0, &list_unittests, 1}, {"init-errors-fatal", 0, 0, 0}, @@ -447,6 +449,12 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } } + else if(strcmp((long_opts[option_index]).name , "pfring-ctype") == 0){ + if (ConfSet("pfring.ctype", optarg, 0) != 1) { + fprintf(stderr, "ERROR: Failed to set pfring cluster type.\n"); + exit(EXIT_FAILURE); + } + } else if(strcmp((long_opts[option_index]).name, "init-errors-fatal") == 0) { if (ConfSet("engine.init_failure_fatal", "1", 0) != 1) { fprintf(stderr, "ERROR: Failed to set engine init_failure_fatal.\n"); diff --git a/src/util-error.c b/src/util-error.c index 4b44b24c70..102476ba60 100644 --- a/src/util-error.c +++ b/src/util-error.c @@ -34,6 +34,14 @@ const char * SCErrorToString(SCError err) CASE_CODE (SC_ERR_PCAP_OPEN_LIVE); CASE_CODE (SC_ERR_PCAP_OPEN_OFFLINE); CASE_CODE (SC_ERR_PCAP_ACTIVATE_HANDLE); + CASE_CODE (SC_ERR_NO_PF_RING); + CASE_CODE (SC_ERR_PF_RING_RECV); + CASE_CODE (SC_ERR_PF_RING_GET_CLUSTERID_FAILED); + CASE_CODE (SC_ERR_PF_RING_GET_INTERFACE_FAILED); + CASE_CODE (SC_ERR_PF_RING_OPEN); + CASE_CODE (SC_ERR_GET_CLUSTER_TYPE_FAILED); + CASE_CODE (SC_ERR_INVALID_CLUSTER_TYPE); + CASE_CODE (SC_ERR_PF_RING_SET_CLUSTER_FAILED); CASE_CODE (SC_ERR_DATALINK_UNIMPLEMENTED); CASE_CODE (SC_ERR_INVALID_SIGNATURE); CASE_CODE (SC_ERR_OPENING_FILE); diff --git a/src/util-error.h b/src/util-error.h index d74ad87fd2..bc4d2a9be0 100644 --- a/src/util-error.h +++ b/src/util-error.h @@ -39,6 +39,14 @@ typedef enum { SC_ERR_PCAP_OPEN_LIVE, SC_ERR_PCAP_OPEN_OFFLINE, SC_ERR_PCAP_ACTIVATE_HANDLE, + SC_ERR_NO_PF_RING, + SC_ERR_PF_RING_RECV, + SC_ERR_PF_RING_GET_CLUSTERID_FAILED, + SC_ERR_PF_RING_GET_INTERFACE_FAILED, + SC_ERR_PF_RING_OPEN, + SC_ERR_GET_CLUSTER_TYPE_FAILED, + SC_ERR_INVALID_CLUSTER_TYPE, + SC_ERR_PF_RING_SET_CLUSTER_FAILED, SC_ERR_DATALINK_UNIMPLEMENTED, SC_ERR_INVALID_SIGNATURE, SC_ERR_OPENING_FILE, diff --git a/suricata.yaml b/suricata.yaml index 4ad70fb69e..9188fa8082 100644 --- a/suricata.yaml +++ b/suricata.yaml @@ -227,6 +227,10 @@ pfring: # clusterid. clusterid: 99 + # Default PF_RING cluster type. PF_RING can load balance per flow or per hash. + # This is only supported in versions of PF_RING > 4.1.1. + ctype: cluster_round_robin + # For FreeBSD ipfw(8) divert(4) support. # Please make sure you have ipfw_load="YES" and ipdivert_load="YES" # in /etc/loader.conf or kldload'ing the appropriate kernel modules.