af-packet: add optional emergency mode

Flush all waiting packets to be in sync with kernel when drop
occurs. This mode can be activated by setting use-emergency-flush
to yes in the interface configuration.
pull/48/merge
Eric Leblond 13 years ago committed by Victor Julien
parent ec76742caa
commit 27b5136bf2

@ -190,6 +190,13 @@ void *ParseAFPConfig(const char *iface)
aconf->iface);
aconf->flags |= AFP_RING_MODE;
}
(void)ConfGetChildValueBool(if_root, "use-emergency-flush", (int *)&boolval);
if (boolval) {
SCLogInfo("Enabling ring emergency flush on iface %s",
aconf->iface);
aconf->flags |= AFP_EMERGENCY_MODE;
}
aconf->copy_mode = AFP_COPY_MODE_NONE;
if (ConfGetChildValue(if_root, "copy-mode", &copymodestr) == 1) {

@ -129,6 +129,7 @@ enum {
AFP_READ_OK,
AFP_READ_FAILURE,
AFP_FAILURE,
AFP_KERNEL_DROP,
};
union thdr {
@ -610,6 +611,7 @@ int AFPReadFromRing(AFPThreadVars *ptv)
Packet *p = NULL;
union thdr h;
struct sockaddr_ll *from;
uint8_t emergency_flush = 0;
/* Loop till we have packets available */
while (1) {
@ -620,7 +622,15 @@ int AFPReadFromRing(AFPThreadVars *ptv)
}
if (h.h2->tp_status == TP_STATUS_KERNEL) {
SCReturnInt(AFP_READ_OK);
if ((emergency_flush) && (ptv->flags & AFP_EMERGENCY_MODE)) {
SCReturnInt(AFP_KERNEL_DROP);
} else {
SCReturnInt(AFP_READ_OK);
}
}
if ((ptv->flags & AFP_EMERGENCY_MODE) && (emergency_flush == 1)) {
h.h2->tp_status = TP_STATUS_KERNEL;
goto next_frame;
}
p = PacketGetFromQueueOrAlloc();
@ -704,6 +714,9 @@ int AFPReadFromRing(AFPThreadVars *ptv)
if (h.h2->tp_status & TP_STATUS_CSUMNOTREADY) {
p->flags |= PKT_IGNORE_CHECKSUM;
}
if (h.h2->tp_status & TP_STATUS_LOSING) {
emergency_flush = 1;
}
}
if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
@ -715,7 +728,11 @@ int AFPReadFromRing(AFPThreadVars *ptv)
SCReturnInt(AFP_FAILURE);
}
h.h2->tp_status = TP_STATUS_KERNEL;
/* release frame if not in zero copy mode */
if (!(ptv->flags & AFP_ZERO_COPY)) {
h.h2->tp_status = TP_STATUS_KERNEL;
}
next_frame:
if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
ptv->frame_offset = 0;
}
@ -838,6 +855,9 @@ TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot)
case AFP_READ_OK:
AFPDumpCounters(ptv, 0);
break;
case AFP_KERNEL_DROP:
AFPDumpCounters(ptv, 1);
break;
}
} else if ((r < 0) && (errno != EINTR)) {
SCLogError(SC_ERR_AFP_READ, "Error reading data from socket: (%d" PRIu32 ") %s",

@ -42,6 +42,7 @@
#define AFP_RING_MODE (1<<0)
#define AFP_ZERO_COPY (1<<1)
#define AFP_SOCK_PROTECT (1<<2)
#define AFP_EMERGENCY_MODE (1<<3)
#define AFP_COPY_MODE_NONE 0
#define AFP_COPY_MODE_TAP 1

@ -236,6 +236,9 @@ af-packet:
# intensive single-flow you could want to set the ring-size independantly of the number
# of threads:
#ring-size: 2048
# On busy system, this could help to set it to yes to recover from a packet drop
# phase. This will result in some packets (at max a ring flush) being non treated.
#use-emergency-flush: yes
# recv buffer size, increase value could improve performance
# buffer-size: 32768
# Set to yes to disable promiscuous mode

Loading…
Cancel
Save