Allow Bro to run in fanout mode.

This commit is contained in:
Kris Nielander 2015-08-09 22:41:28 +02:00
parent f5429ee794
commit d8c9b7255e
9 changed files with 88 additions and 5 deletions

View file

@ -155,6 +155,7 @@ include(TestBigEndian)
test_big_endian(WORDS_BIGENDIAN) test_big_endian(WORDS_BIGENDIAN)
include(CheckSymbolExists) include(CheckSymbolExists)
check_symbol_exists(htonll arpa/inet.h HAVE_BYTEORDER_64) 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(OSSpecific)
include(CheckTypes) include(CheckTypes)

View file

@ -213,6 +213,9 @@
/* Common IPv6 extension structure */ /* Common IPv6 extension structure */
#cmakedefine HAVE_IP6_EXT #cmakedefine HAVE_IP6_EXT
/* Linux packet fanout */
#cmakedefine HAVE_PACKET_FANOUT
/* String with host architecture (e.g., "linux-x86_64") */ /* String with host architecture (e.g., "linux-x86_64") */
#define HOST_ARCHITECTURE "@HOST_ARCHITECTURE@" #define HOST_ARCHITECTURE "@HOST_ARCHITECTURE@"

View file

@ -3710,12 +3710,34 @@ export {
## external harness and shouldn't output anything to the console. ## external harness and shouldn't output anything to the console.
const errors_to_stderr = T &redef; 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; module GLOBAL;
## Number of bytes per packet to capture from live interfaces. ## Number of bytes per packet to capture from live interfaces.
const snaplen = 8192 &redef; const snaplen = 8192 &redef;
## Number of bytes for libpcap buffer. ## Number of bytes per packet to capture from live interfaces.
const bufsize = 128 &redef; const bufsize = 128 &redef;
## Seed for hashes computed internally for probabilistic data structures. Using ## Seed for hashes computed internally for probabilistic data structures. Using

View file

@ -9,6 +9,9 @@ const detect_filtered_trace: bool;
const report_gaps_for_partial: bool; const report_gaps_for_partial: bool;
const exit_only_after_terminate: bool; const exit_only_after_terminate: bool;
const Fanout::enable: bool;
const Fanout::id: count;
const NFS3::return_data: bool; const NFS3::return_data: bool;
const NFS3::return_data_max: count; const NFS3::return_data_max: count;
const NFS3::return_data_first_only: bool; const NFS3::return_data_first_only: bool;

View file

@ -3,6 +3,27 @@
#ifndef IOSOURCE_IOSOURCE_H #ifndef IOSOURCE_IOSOURCE_H
#define IOSOURCE_IOSOURCE_H #define IOSOURCE_IOSOURCE_H
#ifdef HAVE_PACKET_FANOUT
#include <linux/if_packet.h>
#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" { extern "C" {
#include <pcap.h> #include <pcap.h>
} }

View file

@ -73,7 +73,7 @@ int PktSrc::SnapLen() const
int PktSrc::BufSize() const int PktSrc::BufSize() const
{ {
return bufsize; // That's a global too. Change? return bufsize; // That's a global. Change?
} }
bool PktSrc::IsLive() const bool PktSrc::IsLive() const

View file

@ -84,13 +84,12 @@ void PcapSource::OpenLive()
props.netmask = PktSrc::NETMASK_UNKNOWN; props.netmask = PktSrc::NETMASK_UNKNOWN;
#endif #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 // no packets are available. (We can't use set_nonblocking() as it's
// broken on FreeBSD: even when select() indicates that we can read // broken on FreeBSD: even when select() indicates that we can read
// something, we may get nothing if the store buffer hasn't filled up // something, we may get nothing if the store buffer hasn't filled up
// yet.) // yet.)
pd = pcap_create(props.path.c_str(), errbuf); pd = pcap_create(props.path.c_str(), errbuf);
if ( ! pd ) if ( ! pd )
{ {
safe_snprintf(errbuf, sizeof(errbuf), safe_snprintf(errbuf, sizeof(errbuf),
@ -160,6 +159,19 @@ void PcapSource::OpenLive()
// Was closed, couldn't get header size. // Was closed, couldn't get header size.
return; 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; props.is_live = true;
Opened(props); Opened(props);

View file

@ -5,6 +5,13 @@
#include "../PktSrc.h" #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 iosource {
namespace pcap { namespace pcap {

View file

@ -124,6 +124,13 @@ char* proc_status_file = 0;
int snaplen = 0; // this gets set from the scripting-layer's value int snaplen = 0; // this gets set from the scripting-layer's value
int bufsize = 0; 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* md5_type = 0;
OpaqueType* sha1_type = 0; OpaqueType* sha1_type = 0;
OpaqueType* sha256_type = 0; OpaqueType* sha256_type = 0;
@ -991,7 +998,14 @@ int main(int argc, char** argv)
} }
snaplen = internal_val("snaplen")->AsCount(); 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 ) if ( dns_type != DNS_PRIME )
net_init(interfaces, read_files, writefile, do_watchdog); net_init(interfaces, read_files, writefile, do_watchdog);