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->iface);
aconf->flags |= AFP_RING_MODE; 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; aconf->copy_mode = AFP_COPY_MODE_NONE;
if (ConfGetChildValue(if_root, "copy-mode", &copymodestr) == 1) { if (ConfGetChildValue(if_root, "copy-mode", &copymodestr) == 1) {

@ -129,6 +129,7 @@ enum {
AFP_READ_OK, AFP_READ_OK,
AFP_READ_FAILURE, AFP_READ_FAILURE,
AFP_FAILURE, AFP_FAILURE,
AFP_KERNEL_DROP,
}; };
union thdr { union thdr {
@ -610,6 +611,7 @@ int AFPReadFromRing(AFPThreadVars *ptv)
Packet *p = NULL; Packet *p = NULL;
union thdr h; union thdr h;
struct sockaddr_ll *from; struct sockaddr_ll *from;
uint8_t emergency_flush = 0;
/* Loop till we have packets available */ /* Loop till we have packets available */
while (1) { while (1) {
@ -620,8 +622,16 @@ int AFPReadFromRing(AFPThreadVars *ptv)
} }
if (h.h2->tp_status == TP_STATUS_KERNEL) { if (h.h2->tp_status == TP_STATUS_KERNEL) {
if ((emergency_flush) && (ptv->flags & AFP_EMERGENCY_MODE)) {
SCReturnInt(AFP_KERNEL_DROP);
} else {
SCReturnInt(AFP_READ_OK); 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(); p = PacketGetFromQueueOrAlloc();
if (p == NULL) { if (p == NULL) {
@ -704,6 +714,9 @@ int AFPReadFromRing(AFPThreadVars *ptv)
if (h.h2->tp_status & TP_STATUS_CSUMNOTREADY) { if (h.h2->tp_status & TP_STATUS_CSUMNOTREADY) {
p->flags |= PKT_IGNORE_CHECKSUM; 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) { if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
@ -715,7 +728,11 @@ int AFPReadFromRing(AFPThreadVars *ptv)
SCReturnInt(AFP_FAILURE); SCReturnInt(AFP_FAILURE);
} }
/* release frame if not in zero copy mode */
if (!(ptv->flags & AFP_ZERO_COPY)) {
h.h2->tp_status = TP_STATUS_KERNEL; h.h2->tp_status = TP_STATUS_KERNEL;
}
next_frame:
if (++ptv->frame_offset >= ptv->req.tp_frame_nr) { if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
ptv->frame_offset = 0; ptv->frame_offset = 0;
} }
@ -838,6 +855,9 @@ TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot)
case AFP_READ_OK: case AFP_READ_OK:
AFPDumpCounters(ptv, 0); AFPDumpCounters(ptv, 0);
break; break;
case AFP_KERNEL_DROP:
AFPDumpCounters(ptv, 1);
break;
} }
} else if ((r < 0) && (errno != EINTR)) { } else if ((r < 0) && (errno != EINTR)) {
SCLogError(SC_ERR_AFP_READ, "Error reading data from socket: (%d" PRIu32 ") %s", 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_RING_MODE (1<<0)
#define AFP_ZERO_COPY (1<<1) #define AFP_ZERO_COPY (1<<1)
#define AFP_SOCK_PROTECT (1<<2) #define AFP_SOCK_PROTECT (1<<2)
#define AFP_EMERGENCY_MODE (1<<3)
#define AFP_COPY_MODE_NONE 0 #define AFP_COPY_MODE_NONE 0
#define AFP_COPY_MODE_TAP 1 #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 # intensive single-flow you could want to set the ring-size independantly of the number
# of threads: # of threads:
#ring-size: 2048 #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 # recv buffer size, increase value could improve performance
# buffer-size: 32768 # buffer-size: 32768
# Set to yes to disable promiscuous mode # Set to yes to disable promiscuous mode

Loading…
Cancel
Save