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