From 28c467df4ea39134e6e3f0cd7d453e26cffcba28 Mon Sep 17 00:00:00 2001 From: Kris Nielander Date: Sun, 9 Aug 2015 22:08:46 +0200 Subject: [PATCH 1/5] Allowed libpcap buffer size to be set via configuration. --- scripts/base/init-bare.bro | 3 +++ src/Net.h | 3 +++ src/iosource/PktSrc.cc | 5 ++++ src/iosource/PktSrc.h | 5 ++++ src/iosource/pcap/Source.cc | 46 +++++++++++++++++++++++++++++++++++-- src/main.cc | 2 ++ 6 files changed, 62 insertions(+), 2 deletions(-) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 24c6f6f5f1..f28aa66c74 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -3715,6 +3715,9 @@ module GLOBAL; ## Number of bytes per packet to capture from live interfaces. const snaplen = 8192 &redef; +## Number of bytes for libpcap buffer. +const bufsize = 128 &redef; + ## Seed for hashes computed internally for probabilistic data structures. Using ## the same value here will make the hashes compatible between independent Bro ## instances. If left unset, Bro will use a temporary local seed. diff --git a/src/Net.h b/src/Net.h index d19bd9083c..e57c4a8c7f 100644 --- a/src/Net.h +++ b/src/Net.h @@ -73,6 +73,9 @@ extern bool using_communication; // Snaplen passed to libpcap. extern int snaplen; +// Buffer size passed to libpcap. +extern int bufsize; + extern const Packet* current_pkt; extern int current_dispatched; extern double current_timestamp; diff --git a/src/iosource/PktSrc.cc b/src/iosource/PktSrc.cc index f44aae77c5..125a72c052 100644 --- a/src/iosource/PktSrc.cc +++ b/src/iosource/PktSrc.cc @@ -71,6 +71,11 @@ int PktSrc::SnapLen() const return snaplen; // That's a global. Change? } +int PktSrc::BufSize() const + { + return bufsize; // That's a global too. Change? + } + bool PktSrc::IsLive() const { return props.is_live; diff --git a/src/iosource/PktSrc.h b/src/iosource/PktSrc.h index bf4c811dca..d6ff03f5b5 100644 --- a/src/iosource/PktSrc.h +++ b/src/iosource/PktSrc.h @@ -100,6 +100,11 @@ public: */ int SnapLen() const; + /** + * Returns the buffer size for this source. + */ + int BufSize() const; + /** * In pseudo-realtime mode, returns the logical timestamp of the * current packet. Undefined if not running pseudo-realtime mode. diff --git a/src/iosource/pcap/Source.cc b/src/iosource/pcap/Source.cc index 2af21bf9b4..9c5ba2819a 100644 --- a/src/iosource/pcap/Source.cc +++ b/src/iosource/pcap/Source.cc @@ -89,11 +89,53 @@ void PcapSource::OpenLive() // broken on FreeBSD: even when select() indicates that we can read // something, we may get nothing if the store buffer hasn't filled up // yet.) - pd = pcap_open_live(props.path.c_str(), SnapLen(), 1, 1, tmp_errbuf); + pd = pcap_create(props.path.c_str(), errbuf); if ( ! pd ) { - Error(tmp_errbuf); + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_create: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_set_snaplen(pd, SnapLen()) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_set_snaplen: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_set_promisc(pd, 1) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_set_promisc: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_set_timeout(pd, 1) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_set_timeout: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_set_buffer_size(pd, BufSize()) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_set_buffer_size: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_activate(pd) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_activate: %s", pcap_geterr(pd)); + Error(errbuf); return; } diff --git a/src/main.cc b/src/main.cc index 64acb408ea..347d01137e 100644 --- a/src/main.cc +++ b/src/main.cc @@ -122,6 +122,7 @@ vector params; set requested_plugins; char* proc_status_file = 0; int snaplen = 0; // this gets set from the scripting-layer's value +int bufsize = 0; OpaqueType* md5_type = 0; OpaqueType* sha1_type = 0; @@ -990,6 +991,7 @@ int main(int argc, char** argv) } snaplen = internal_val("snaplen")->AsCount(); + bufsize = internal_val("bufsize")->AsCount() * 1024 * 1024; // Size in Mbytes if ( dns_type != DNS_PRIME ) net_init(interfaces, read_files, writefile, do_watchdog); From 54078407d43d3503603d9edfc16302bf52883e3b Mon Sep 17 00:00:00 2001 From: Kris Nielander Date: Sun, 9 Aug 2015 22:41:28 +0200 Subject: [PATCH 2/5] Allow Bro to run in fanout mode. --- CMakeLists.txt | 1 + bro-config.h.in | 3 +++ scripts/base/init-bare.bro | 24 +++++++++++++++++++++++- src/const.bif | 3 +++ src/iosource/IOSource.h | 21 +++++++++++++++++++++ src/iosource/PktSrc.cc | 2 +- src/iosource/pcap/Source.cc | 16 ++++++++++++++-- src/iosource/pcap/Source.h | 7 +++++++ src/main.cc | 16 +++++++++++++++- 9 files changed, 88 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dbf8109ad..f345514aa9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,6 +155,7 @@ include(TestBigEndian) test_big_endian(WORDS_BIGENDIAN) include(CheckSymbolExists) check_symbol_exists(htonll arpa/inet.h HAVE_BYTEORDER_64) +check_symbol_exists(PACKET_FANOUT linux/if_packet.h HAVE_PACKET_FANOUT) include(OSSpecific) include(CheckTypes) diff --git a/bro-config.h.in b/bro-config.h.in index 755a9eee98..fd24a1fe30 100644 --- a/bro-config.h.in +++ b/bro-config.h.in @@ -213,6 +213,9 @@ /* Common IPv6 extension structure */ #cmakedefine HAVE_IP6_EXT +/* Linux packet fanout */ +#cmakedefine HAVE_PACKET_FANOUT + /* String with host architecture (e.g., "linux-x86_64") */ #define HOST_ARCHITECTURE "@HOST_ARCHITECTURE@" diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index f28aa66c74..0097e4d47b 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -3710,12 +3710,34 @@ export { ## external harness and shouldn't output anything to the console. const errors_to_stderr = T &redef; } + +module Fanout; + +type Method: enum { + METHOD_HASH = 0, + METHOD_LB = 1, + METHOD_CPU = 2, + METHOD_ROLLOVER = 3 +}; + +type Flag: enum { + FLAG_NONE = 0, + FLAG_DEFRAG = 0x8000, + FLAG_ROLLOVER = 0x1000 +}; + +export { + const enable = F &redef; + const id = 0 &redef; + const method = METHOD_HASH &redef; + const flag = FLAG_NONE &redef; +} module GLOBAL; ## Number of bytes per packet to capture from live interfaces. const snaplen = 8192 &redef; -## Number of bytes for libpcap buffer. +## Number of bytes per packet to capture from live interfaces. const bufsize = 128 &redef; ## Seed for hashes computed internally for probabilistic data structures. Using diff --git a/src/const.bif b/src/const.bif index 0ba168ca85..f96b15818b 100644 --- a/src/const.bif +++ b/src/const.bif @@ -9,6 +9,9 @@ const detect_filtered_trace: bool; const report_gaps_for_partial: bool; const exit_only_after_terminate: bool; +const Fanout::enable: bool; +const Fanout::id: count; + const NFS3::return_data: bool; const NFS3::return_data_max: count; const NFS3::return_data_first_only: bool; diff --git a/src/iosource/IOSource.h b/src/iosource/IOSource.h index df82012268..a129429e0e 100644 --- a/src/iosource/IOSource.h +++ b/src/iosource/IOSource.h @@ -3,6 +3,27 @@ #ifndef IOSOURCE_IOSOURCE_H #define IOSOURCE_IOSOURCE_H +#ifdef HAVE_PACKET_FANOUT +#include +#ifndef PACKET_FANOUT +#define PACKET_FANOUT 18 +#define PACKET_FANOUT_HASH 0 +#define PACKET_FANOUT_LB 1 +#define PACKET_FANOUT_CPU 2 +#define PACKET_FANOUT_FLAG_DEFRAG 0x8000 + +#ifndef PACKET_FANOUT_ROLLOVER +#define PACKET_FANOUT_ROLLOVER 3 +#endif + +#ifndef PACKET_FANOUT_FLAG_ROLLOVER +#define PACKET_FANOUT_FLAG_ROLLOVER 0x1000 +#endif + +#define PACKET_FANOUT_FLAG_NONE -1 +#endif /* PACKET_FANOUT */ +#endif /* HAVE_PACKET_FANOUT */ + extern "C" { #include } diff --git a/src/iosource/PktSrc.cc b/src/iosource/PktSrc.cc index 125a72c052..42be77cb21 100644 --- a/src/iosource/PktSrc.cc +++ b/src/iosource/PktSrc.cc @@ -73,7 +73,7 @@ int PktSrc::SnapLen() const int PktSrc::BufSize() const { - return bufsize; // That's a global too. Change? + return bufsize; // That's a global. Change? } bool PktSrc::IsLive() const diff --git a/src/iosource/pcap/Source.cc b/src/iosource/pcap/Source.cc index 9c5ba2819a..e430dfc6a7 100644 --- a/src/iosource/pcap/Source.cc +++ b/src/iosource/pcap/Source.cc @@ -84,13 +84,12 @@ void PcapSource::OpenLive() props.netmask = PktSrc::NETMASK_UNKNOWN; #endif - // We use the smallest time-out possible to return almost immediately if + // ### We use the smallest time-out possible to return almost immediately if // no packets are available. (We can't use set_nonblocking() as it's // broken on FreeBSD: even when select() indicates that we can read // something, we may get nothing if the store buffer hasn't filled up // yet.) pd = pcap_create(props.path.c_str(), errbuf); - if ( ! pd ) { safe_snprintf(errbuf, sizeof(errbuf), @@ -160,6 +159,19 @@ void PcapSource::OpenLive() // Was closed, couldn't get header size. return; +#ifdef HAVE_PACKET_FANOUT + /* Turn on cluster mode for the device. */ + if ( fanout_enable ) + { + uint32_t fanout_arg = (fanout_method << 16) | (fanout_id & 0xffff); + if (setsockopt(props.selectable_fd, SOL_PACKET, PACKET_FANOUT, &fanout_arg, sizeof(fanout_arg)) == -1) + { + Error(fmt("%s: setsockopt: %s", __FUNCTION__, strerror(errno))); + return; + } + } +#endif + props.is_live = true; Opened(props); diff --git a/src/iosource/pcap/Source.h b/src/iosource/pcap/Source.h index f627e30afa..2f169f7819 100644 --- a/src/iosource/pcap/Source.h +++ b/src/iosource/pcap/Source.h @@ -5,6 +5,13 @@ #include "../PktSrc.h" +#ifdef HAVE_PACKET_FANOUT +extern bool fanout_enable; +extern int fanout_id; +extern int fanout_method; +extern int fanout_flag; +#endif + namespace iosource { namespace pcap { diff --git a/src/main.cc b/src/main.cc index 347d01137e..b7d1bbfa40 100644 --- a/src/main.cc +++ b/src/main.cc @@ -124,6 +124,13 @@ char* proc_status_file = 0; int snaplen = 0; // this gets set from the scripting-layer's value int bufsize = 0; +#ifdef HAVE_PACKET_FANOUT +bool fanout_enable = false; +int fanout_id = 0; +int fanout_method = PACKET_FANOUT_HASH; +int fanout_flag = 0; +#endif + OpaqueType* md5_type = 0; OpaqueType* sha1_type = 0; OpaqueType* sha256_type = 0; @@ -991,7 +998,14 @@ int main(int argc, char** argv) } snaplen = internal_val("snaplen")->AsCount(); - bufsize = internal_val("bufsize")->AsCount() * 1024 * 1024; // Size in Mbytes + bufsize = internal_val("bufsize")->AsCount() * 1024 * 1024; + +#ifdef HAVE_PACKET_FANOUT + fanout_enable = internal_val("Fanout::enable")->AsBool(); + fanout_id = internal_val("Fanout::id")->AsCount(); + fanout_method = internal_val("Fanout::method")->AsEnum(); + fanout_flag = internal_val("Fanout::flag")->AsEnum(); +#endif if ( dns_type != DNS_PRIME ) net_init(interfaces, read_files, writefile, do_watchdog); From f5429ee794814d7b102e8d29796d1498ccadbeb7 Mon Sep 17 00:00:00 2001 From: Kris Nielander Date: Sun, 9 Aug 2015 22:08:46 +0200 Subject: [PATCH 3/5] Allow libpcap buffer size to be set manually. --- scripts/base/init-bare.bro | 3 +++ src/Net.h | 3 +++ src/iosource/PktSrc.cc | 5 ++++ src/iosource/PktSrc.h | 5 ++++ src/iosource/pcap/Source.cc | 46 +++++++++++++++++++++++++++++++++++-- src/main.cc | 2 ++ 6 files changed, 62 insertions(+), 2 deletions(-) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 24c6f6f5f1..f28aa66c74 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -3715,6 +3715,9 @@ module GLOBAL; ## Number of bytes per packet to capture from live interfaces. const snaplen = 8192 &redef; +## Number of bytes for libpcap buffer. +const bufsize = 128 &redef; + ## Seed for hashes computed internally for probabilistic data structures. Using ## the same value here will make the hashes compatible between independent Bro ## instances. If left unset, Bro will use a temporary local seed. diff --git a/src/Net.h b/src/Net.h index d19bd9083c..e57c4a8c7f 100644 --- a/src/Net.h +++ b/src/Net.h @@ -73,6 +73,9 @@ extern bool using_communication; // Snaplen passed to libpcap. extern int snaplen; +// Buffer size passed to libpcap. +extern int bufsize; + extern const Packet* current_pkt; extern int current_dispatched; extern double current_timestamp; diff --git a/src/iosource/PktSrc.cc b/src/iosource/PktSrc.cc index f44aae77c5..125a72c052 100644 --- a/src/iosource/PktSrc.cc +++ b/src/iosource/PktSrc.cc @@ -71,6 +71,11 @@ int PktSrc::SnapLen() const return snaplen; // That's a global. Change? } +int PktSrc::BufSize() const + { + return bufsize; // That's a global too. Change? + } + bool PktSrc::IsLive() const { return props.is_live; diff --git a/src/iosource/PktSrc.h b/src/iosource/PktSrc.h index bf4c811dca..d6ff03f5b5 100644 --- a/src/iosource/PktSrc.h +++ b/src/iosource/PktSrc.h @@ -100,6 +100,11 @@ public: */ int SnapLen() const; + /** + * Returns the buffer size for this source. + */ + int BufSize() const; + /** * In pseudo-realtime mode, returns the logical timestamp of the * current packet. Undefined if not running pseudo-realtime mode. diff --git a/src/iosource/pcap/Source.cc b/src/iosource/pcap/Source.cc index 2af21bf9b4..9c5ba2819a 100644 --- a/src/iosource/pcap/Source.cc +++ b/src/iosource/pcap/Source.cc @@ -89,11 +89,53 @@ void PcapSource::OpenLive() // broken on FreeBSD: even when select() indicates that we can read // something, we may get nothing if the store buffer hasn't filled up // yet.) - pd = pcap_open_live(props.path.c_str(), SnapLen(), 1, 1, tmp_errbuf); + pd = pcap_create(props.path.c_str(), errbuf); if ( ! pd ) { - Error(tmp_errbuf); + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_create: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_set_snaplen(pd, SnapLen()) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_set_snaplen: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_set_promisc(pd, 1) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_set_promisc: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_set_timeout(pd, 1) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_set_timeout: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_set_buffer_size(pd, BufSize()) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_set_buffer_size: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_activate(pd) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_activate: %s", pcap_geterr(pd)); + Error(errbuf); return; } diff --git a/src/main.cc b/src/main.cc index 64acb408ea..347d01137e 100644 --- a/src/main.cc +++ b/src/main.cc @@ -122,6 +122,7 @@ vector params; set requested_plugins; char* proc_status_file = 0; int snaplen = 0; // this gets set from the scripting-layer's value +int bufsize = 0; OpaqueType* md5_type = 0; OpaqueType* sha1_type = 0; @@ -990,6 +991,7 @@ int main(int argc, char** argv) } snaplen = internal_val("snaplen")->AsCount(); + bufsize = internal_val("bufsize")->AsCount() * 1024 * 1024; // Size in Mbytes if ( dns_type != DNS_PRIME ) net_init(interfaces, read_files, writefile, do_watchdog); From d8c9b7255e053aaf054145c08d55b1550d5d69d4 Mon Sep 17 00:00:00 2001 From: Kris Nielander Date: Sun, 9 Aug 2015 22:41:28 +0200 Subject: [PATCH 4/5] Allow Bro to run in fanout mode. --- CMakeLists.txt | 1 + bro-config.h.in | 3 +++ scripts/base/init-bare.bro | 24 +++++++++++++++++++++++- src/const.bif | 3 +++ src/iosource/IOSource.h | 21 +++++++++++++++++++++ src/iosource/PktSrc.cc | 2 +- src/iosource/pcap/Source.cc | 16 ++++++++++++++-- src/iosource/pcap/Source.h | 7 +++++++ src/main.cc | 16 +++++++++++++++- 9 files changed, 88 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dbf8109ad..f345514aa9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,6 +155,7 @@ include(TestBigEndian) test_big_endian(WORDS_BIGENDIAN) include(CheckSymbolExists) check_symbol_exists(htonll arpa/inet.h HAVE_BYTEORDER_64) +check_symbol_exists(PACKET_FANOUT linux/if_packet.h HAVE_PACKET_FANOUT) include(OSSpecific) include(CheckTypes) diff --git a/bro-config.h.in b/bro-config.h.in index 755a9eee98..fd24a1fe30 100644 --- a/bro-config.h.in +++ b/bro-config.h.in @@ -213,6 +213,9 @@ /* Common IPv6 extension structure */ #cmakedefine HAVE_IP6_EXT +/* Linux packet fanout */ +#cmakedefine HAVE_PACKET_FANOUT + /* String with host architecture (e.g., "linux-x86_64") */ #define HOST_ARCHITECTURE "@HOST_ARCHITECTURE@" diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index f28aa66c74..0097e4d47b 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -3710,12 +3710,34 @@ export { ## external harness and shouldn't output anything to the console. const errors_to_stderr = T &redef; } + +module Fanout; + +type Method: enum { + METHOD_HASH = 0, + METHOD_LB = 1, + METHOD_CPU = 2, + METHOD_ROLLOVER = 3 +}; + +type Flag: enum { + FLAG_NONE = 0, + FLAG_DEFRAG = 0x8000, + FLAG_ROLLOVER = 0x1000 +}; + +export { + const enable = F &redef; + const id = 0 &redef; + const method = METHOD_HASH &redef; + const flag = FLAG_NONE &redef; +} module GLOBAL; ## Number of bytes per packet to capture from live interfaces. const snaplen = 8192 &redef; -## Number of bytes for libpcap buffer. +## Number of bytes per packet to capture from live interfaces. const bufsize = 128 &redef; ## Seed for hashes computed internally for probabilistic data structures. Using diff --git a/src/const.bif b/src/const.bif index 0ba168ca85..f96b15818b 100644 --- a/src/const.bif +++ b/src/const.bif @@ -9,6 +9,9 @@ const detect_filtered_trace: bool; const report_gaps_for_partial: bool; const exit_only_after_terminate: bool; +const Fanout::enable: bool; +const Fanout::id: count; + const NFS3::return_data: bool; const NFS3::return_data_max: count; const NFS3::return_data_first_only: bool; diff --git a/src/iosource/IOSource.h b/src/iosource/IOSource.h index df82012268..a129429e0e 100644 --- a/src/iosource/IOSource.h +++ b/src/iosource/IOSource.h @@ -3,6 +3,27 @@ #ifndef IOSOURCE_IOSOURCE_H #define IOSOURCE_IOSOURCE_H +#ifdef HAVE_PACKET_FANOUT +#include +#ifndef PACKET_FANOUT +#define PACKET_FANOUT 18 +#define PACKET_FANOUT_HASH 0 +#define PACKET_FANOUT_LB 1 +#define PACKET_FANOUT_CPU 2 +#define PACKET_FANOUT_FLAG_DEFRAG 0x8000 + +#ifndef PACKET_FANOUT_ROLLOVER +#define PACKET_FANOUT_ROLLOVER 3 +#endif + +#ifndef PACKET_FANOUT_FLAG_ROLLOVER +#define PACKET_FANOUT_FLAG_ROLLOVER 0x1000 +#endif + +#define PACKET_FANOUT_FLAG_NONE -1 +#endif /* PACKET_FANOUT */ +#endif /* HAVE_PACKET_FANOUT */ + extern "C" { #include } diff --git a/src/iosource/PktSrc.cc b/src/iosource/PktSrc.cc index 125a72c052..42be77cb21 100644 --- a/src/iosource/PktSrc.cc +++ b/src/iosource/PktSrc.cc @@ -73,7 +73,7 @@ int PktSrc::SnapLen() const int PktSrc::BufSize() const { - return bufsize; // That's a global too. Change? + return bufsize; // That's a global. Change? } bool PktSrc::IsLive() const diff --git a/src/iosource/pcap/Source.cc b/src/iosource/pcap/Source.cc index 9c5ba2819a..e430dfc6a7 100644 --- a/src/iosource/pcap/Source.cc +++ b/src/iosource/pcap/Source.cc @@ -84,13 +84,12 @@ void PcapSource::OpenLive() props.netmask = PktSrc::NETMASK_UNKNOWN; #endif - // We use the smallest time-out possible to return almost immediately if + // ### We use the smallest time-out possible to return almost immediately if // no packets are available. (We can't use set_nonblocking() as it's // broken on FreeBSD: even when select() indicates that we can read // something, we may get nothing if the store buffer hasn't filled up // yet.) pd = pcap_create(props.path.c_str(), errbuf); - if ( ! pd ) { safe_snprintf(errbuf, sizeof(errbuf), @@ -160,6 +159,19 @@ void PcapSource::OpenLive() // Was closed, couldn't get header size. return; +#ifdef HAVE_PACKET_FANOUT + /* Turn on cluster mode for the device. */ + if ( fanout_enable ) + { + uint32_t fanout_arg = (fanout_method << 16) | (fanout_id & 0xffff); + if (setsockopt(props.selectable_fd, SOL_PACKET, PACKET_FANOUT, &fanout_arg, sizeof(fanout_arg)) == -1) + { + Error(fmt("%s: setsockopt: %s", __FUNCTION__, strerror(errno))); + return; + } + } +#endif + props.is_live = true; Opened(props); diff --git a/src/iosource/pcap/Source.h b/src/iosource/pcap/Source.h index f627e30afa..2f169f7819 100644 --- a/src/iosource/pcap/Source.h +++ b/src/iosource/pcap/Source.h @@ -5,6 +5,13 @@ #include "../PktSrc.h" +#ifdef HAVE_PACKET_FANOUT +extern bool fanout_enable; +extern int fanout_id; +extern int fanout_method; +extern int fanout_flag; +#endif + namespace iosource { namespace pcap { diff --git a/src/main.cc b/src/main.cc index 347d01137e..b7d1bbfa40 100644 --- a/src/main.cc +++ b/src/main.cc @@ -124,6 +124,13 @@ char* proc_status_file = 0; int snaplen = 0; // this gets set from the scripting-layer's value int bufsize = 0; +#ifdef HAVE_PACKET_FANOUT +bool fanout_enable = false; +int fanout_id = 0; +int fanout_method = PACKET_FANOUT_HASH; +int fanout_flag = 0; +#endif + OpaqueType* md5_type = 0; OpaqueType* sha1_type = 0; OpaqueType* sha256_type = 0; @@ -991,7 +998,14 @@ int main(int argc, char** argv) } snaplen = internal_val("snaplen")->AsCount(); - bufsize = internal_val("bufsize")->AsCount() * 1024 * 1024; // Size in Mbytes + bufsize = internal_val("bufsize")->AsCount() * 1024 * 1024; + +#ifdef HAVE_PACKET_FANOUT + fanout_enable = internal_val("Fanout::enable")->AsBool(); + fanout_id = internal_val("Fanout::id")->AsCount(); + fanout_method = internal_val("Fanout::method")->AsEnum(); + fanout_flag = internal_val("Fanout::flag")->AsEnum(); +#endif if ( dns_type != DNS_PRIME ) net_init(interfaces, read_files, writefile, do_watchdog); From ba4c816b0e38e6cb50f6d0a201ccbfe67589bc3c Mon Sep 17 00:00:00 2001 From: Kris Nielander Date: Mon, 24 Aug 2015 23:45:21 +0200 Subject: [PATCH 5/5] Refactored patch (removed options, less ambiguous name) --- scripts/base/init-bare.bro | 28 ++++++++++------------------ src/const.bif | 4 ++-- src/iosource/IOSource.h | 17 ----------------- src/iosource/pcap/Source.cc | 10 +++++++--- src/iosource/pcap/Source.h | 7 +++---- src/main.cc | 14 ++++++-------- 6 files changed, 28 insertions(+), 52 deletions(-) diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 0097e4d47b..e2b0e169df 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -3710,28 +3710,20 @@ export { ## external harness and shouldn't output anything to the console. const errors_to_stderr = T &redef; } +module GLOBAL; -module Fanout; - -type Method: enum { - METHOD_HASH = 0, - METHOD_LB = 1, - METHOD_CPU = 2, - METHOD_ROLLOVER = 3 -}; - -type Flag: enum { - FLAG_NONE = 0, - FLAG_DEFRAG = 0x8000, - FLAG_ROLLOVER = 0x1000 -}; - +module PacketFanout; export { + ## Toggle whether to do packet fanout. const enable = F &redef; + + ## The packet fanout id should be shared amongst worker processes operating + ## the same socket. const id = 0 &redef; - const method = METHOD_HASH &redef; - const flag = FLAG_NONE &redef; -} + + ## If true, causes packets to be defragmented before fanout is applied. + const flag_defrag = T &redef; +} # end export module GLOBAL; ## Number of bytes per packet to capture from live interfaces. diff --git a/src/const.bif b/src/const.bif index f96b15818b..2129a22578 100644 --- a/src/const.bif +++ b/src/const.bif @@ -9,8 +9,8 @@ const detect_filtered_trace: bool; const report_gaps_for_partial: bool; const exit_only_after_terminate: bool; -const Fanout::enable: bool; -const Fanout::id: count; +const PacketFanout::enable: bool; +const PacketFanout::id: count; const NFS3::return_data: bool; const NFS3::return_data_max: count; diff --git a/src/iosource/IOSource.h b/src/iosource/IOSource.h index a129429e0e..356b8eee70 100644 --- a/src/iosource/IOSource.h +++ b/src/iosource/IOSource.h @@ -5,25 +5,8 @@ #ifdef HAVE_PACKET_FANOUT #include -#ifndef PACKET_FANOUT -#define PACKET_FANOUT 18 -#define PACKET_FANOUT_HASH 0 -#define PACKET_FANOUT_LB 1 -#define PACKET_FANOUT_CPU 2 -#define PACKET_FANOUT_FLAG_DEFRAG 0x8000 - -#ifndef PACKET_FANOUT_ROLLOVER -#define PACKET_FANOUT_ROLLOVER 3 #endif -#ifndef PACKET_FANOUT_FLAG_ROLLOVER -#define PACKET_FANOUT_FLAG_ROLLOVER 0x1000 -#endif - -#define PACKET_FANOUT_FLAG_NONE -1 -#endif /* PACKET_FANOUT */ -#endif /* HAVE_PACKET_FANOUT */ - extern "C" { #include } diff --git a/src/iosource/pcap/Source.cc b/src/iosource/pcap/Source.cc index e430dfc6a7..9dc36cfa5f 100644 --- a/src/iosource/pcap/Source.cc +++ b/src/iosource/pcap/Source.cc @@ -161,10 +161,14 @@ void PcapSource::OpenLive() #ifdef HAVE_PACKET_FANOUT /* Turn on cluster mode for the device. */ - if ( fanout_enable ) + if ( packet_fanout_enable ) { - uint32_t fanout_arg = (fanout_method << 16) | (fanout_id & 0xffff); - if (setsockopt(props.selectable_fd, SOL_PACKET, PACKET_FANOUT, &fanout_arg, sizeof(fanout_arg)) == -1) + uint32_t packet_fanout_arg = (PACKET_FANOUT_HASH << 16) | (packet_fanout_id & 0xffff); + + if ( packet_fanout_flag_defrag ) + packet_fanout_arg |= (PACKET_FANOUT_FLAG_DEFRAG << 16); + + if (setsockopt(props.selectable_fd, SOL_PACKET, PACKET_FANOUT, &packet_fanout_arg, sizeof(packet_fanout_arg)) == -1) { Error(fmt("%s: setsockopt: %s", __FUNCTION__, strerror(errno))); return; diff --git a/src/iosource/pcap/Source.h b/src/iosource/pcap/Source.h index 2f169f7819..0e618e06e3 100644 --- a/src/iosource/pcap/Source.h +++ b/src/iosource/pcap/Source.h @@ -6,10 +6,9 @@ #include "../PktSrc.h" #ifdef HAVE_PACKET_FANOUT -extern bool fanout_enable; -extern int fanout_id; -extern int fanout_method; -extern int fanout_flag; +extern bool packet_fanout_enable; +extern int packet_fanout_id; +extern bool packet_fanout_flag_defrag; #endif namespace iosource { diff --git a/src/main.cc b/src/main.cc index b7d1bbfa40..207dae6193 100644 --- a/src/main.cc +++ b/src/main.cc @@ -125,10 +125,9 @@ int snaplen = 0; // this gets set from the scripting-layer's value int bufsize = 0; #ifdef HAVE_PACKET_FANOUT -bool fanout_enable = false; -int fanout_id = 0; -int fanout_method = PACKET_FANOUT_HASH; -int fanout_flag = 0; +bool packet_fanout_enable = false; +int packet_fanout_id = 0; +bool packet_fanout_flag_defrag = false; #endif OpaqueType* md5_type = 0; @@ -1001,10 +1000,9 @@ int main(int argc, char** argv) bufsize = internal_val("bufsize")->AsCount() * 1024 * 1024; #ifdef HAVE_PACKET_FANOUT - fanout_enable = internal_val("Fanout::enable")->AsBool(); - fanout_id = internal_val("Fanout::id")->AsCount(); - fanout_method = internal_val("Fanout::method")->AsEnum(); - fanout_flag = internal_val("Fanout::flag")->AsEnum(); + packet_fanout_enable = internal_val("PacketFanout::enable")->AsBool(); + packet_fanout_id = internal_val("PacketFanout::id")->AsCount(); + packet_fanout_flag_defrag = internal_val("PacketFanout::flag_defrag")->AsBool(); #endif if ( dns_type != DNS_PRIME )