From 8879df80049a1db693e1f196f50928cf2472f12f Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Thu, 5 Jul 2012 07:41:16 +0200 Subject: [PATCH] af-packet: improve mmaped running mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mmaped mode was using a too small ring buffer size which was not able to handle burst of packets coming from the network. This may explain the important packet loss rate observed by Edward Fjellskål. This patch increases the default value and adds a ring-size variable which can be used to manually tune the value. --- src/runmode-af-packet.c | 17 +++++++++++++++++ src/source-af-packet.c | 4 +++- src/source-af-packet.h | 2 ++ suricata.yaml.in | 6 ++++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/runmode-af-packet.c b/src/runmode-af-packet.c index 18f1b9b305..d9309a4ec4 100644 --- a/src/runmode-af-packet.c +++ b/src/runmode-af-packet.c @@ -50,6 +50,8 @@ #include "source-af-packet.h" +extern int max_pending_packets; + static const char *default_mode_auto = NULL; static const char *default_mode_autofp = NULL; @@ -222,6 +224,21 @@ void *ParseAFPConfig(const char *iface) } else { aconf->buffer_size = 0; } + if ((ConfGetChildValueInt(if_root, "ring-size", &value)) == 1) { + aconf->ring_size = value; + if (value * aconf->threads < max_pending_packets) { + aconf->ring_size = max_pending_packets / aconf->threads + 1; + SCLogWarning(SC_ERR_AFP_CREATE, "Inefficient setup: ring-size < max_pending_packets. " + "Resetting to decent value %d.", aconf->ring_size); + /* We want at least that max_pending_packets packets can be handled by the + * interface. This is generous if we have multiple interfaces listening. */ + } + } else { + /* We want that max_pending_packets packets can be handled by suricata + * for this interface. To take burst into account we multiply the obtained + * size by 2. */ + aconf->ring_size = max_pending_packets * 2 / aconf->threads; + } (void)ConfGetChildValueBool(if_root, "disable-promisc", (int *)&boolval); if (boolval) { diff --git a/src/source-af-packet.c b/src/source-af-packet.c index 0ed71e1376..82e5c345ee 100644 --- a/src/source-af-packet.c +++ b/src/source-af-packet.c @@ -181,6 +181,7 @@ typedef struct AFPThreadVars_ char *ring_buf; char *frame_buf; unsigned int frame_offset; + int ring_size; } AFPThreadVars; TmEcode ReceiveAFP(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); @@ -668,7 +669,7 @@ frame size: TPACKET_ALIGN(snaplen + TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + siz SCLogInfo("frame size to big"); return -1; } - ptv->req.tp_frame_nr = max_pending_packets; /* Warrior mode */ + ptv->req.tp_frame_nr = ptv->ring_size; ptv->req.tp_block_nr = ptv->req.tp_frame_nr / frames_per_block + 1; /* exact division */ ptv->req.tp_frame_nr = ptv->req.tp_block_nr * frames_per_block; @@ -971,6 +972,7 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) { } ptv->buffer_size = afpconfig->buffer_size; + ptv->ring_size = afpconfig->ring_size; ptv->promisc = afpconfig->promisc; ptv->checksum_mode = afpconfig->checksum_mode; diff --git a/src/source-af-packet.h b/src/source-af-packet.h index 40c1d92c1b..02b1d63a2f 100644 --- a/src/source-af-packet.h +++ b/src/source-af-packet.h @@ -52,6 +52,8 @@ typedef struct AFPIfaceConfig_ int threads; /* socket buffer size */ int buffer_size; + /* ring size in number of packets */ + int ring_size; /* cluster param */ int cluster_id; int cluster_type; diff --git a/suricata.yaml.in b/suricata.yaml.in index 7ffb3ae9c9..4fc9ef6dc3 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -230,6 +230,12 @@ af-packet: defrag: yes # To use the ring feature of AF_PACKET, set 'use-mmap' to yes use-mmap: yes + # Ring size will be computed with respect to max_pending_packets and number + # of threads. You can set manually the ring size in number of packets by setting + # the following value. If you are using flow cluster-type and have really network + # intensive single-flow you could want to set the ring-size independantly of the number + # of threads: + #ring-size: 2048 # recv buffer size, increase value could improve performance # buffer-size: 32768 # Set to yes to disable promiscuous mode