#include "source-nfq.h"
#include "source-ipfw.h"
#include "source-pcap.h"
+#include "source-af-packet.h"
#include "action-globals.h"
#ifdef IPFW
IPFWPacketVars ipfw_v;
#endif /* IPFW */
+#ifdef AF_PACKET
+ AFPPacketVars afp_v;
+#endif
/** libpcap vars: shared by Pcap Live mode and Pcap File mode */
PcapPacketVars pcap_v;
int debuglog_flowbits_names_len;
const char **debuglog_flowbits_names;
+ /** The release function for packet data */
+ TmEcode (*ReleaseData)(ThreadVars *, struct Packet_ *);
+
/* pkt vars */
PktVar *pktvar;
SCReturnInt(AFP_READ_OK);
}
+TmEcode AFPReleaseDataFromRing(ThreadVars *t, Packet *p)
+{
+ if (p->afp_v.relptr) {
+ union thdr h;
+ h.raw = p->afp_v.relptr;
+ h.h2->tp_status = TP_STATUS_KERNEL;
+ return TM_ECODE_OK;
+ }
+ return TM_ECODE_FAILED;
+}
+
/**
* \brief AF packet read function for ring
*
h.raw = (((union thdr **)ptv->frame_buf)[ptv->frame_offset]);
if (h.raw == NULL) {
SCReturnInt(AFP_FAILURE);
+ } else {
+ if (ptv->flags & AFP_RING_MODE) {
+ p->afp_v.relptr = h.raw;
+ p->ReleaseData = AFPReleaseDataFromRing;
+ }
}
if (h.h2->tp_status == TP_STATUS_KERNEL) {
SCReturnInt(AFP_READ_OK);
SCLogInfo("Enabling zero copy mode");
}
+ /* If we are in RING mode, then we can use ZERO copy
+ * by using the data release mechanism */
+ if (ptv->flags & AFP_RING_MODE) {
+ ptv->flags |= AFP_ZERO_COPY;
+ SCLogInfo("Enabling zero copy mode by using data release call");
+ }
+
r = AFPCreateSocket(ptv, ptv->iface, 1);
if (r < 0) {
SCLogError(SC_ERR_AFP_CREATE, "Couldn't init AF_PACKET socket");
void (*DerefFunc)(void *);
} AFPIfaceConfig;
+/* per packet AF_PACKET vars */
+typedef struct AFPPacketVars_
+{
+ void *relptr;
+} AFPPacketVars;
+
+
void TmModuleReceiveAFPRegister (void);
void TmModuleDecodeAFPRegister (void);
FlowDecrUsecnt(p->root->flow);
/* if p->root uses extended data, free them */
+ if (p->root->ReleaseData) {
+ if (p->root->ReleaseData(t, p->root) == TM_ECODE_FAILED) {
+ SCLogWarning(SC_ERR_INVALID_ACTION,
+ "Unable to release packet data");
+ }
+ }
if (p->root->ext_pkt) {
- SCFree(p->root->ext_pkt);
+ if (!(p->root->flags & PKT_ZERO_COPY)) {
+ SCFree(p->root->ext_pkt);
+ }
p->root->ext_pkt = NULL;
}
if (p->root->flags & PKT_ALLOC) {
PACKET_RECYCLE(p->root);
RingBufferMrMwPut(ringbuffer, (void *)p->root);
}
+
+ }
+
+ if (p->ReleaseData) {
+ if (p->ReleaseData(t, p) == TM_ECODE_FAILED) {
+ SCLogWarning(SC_ERR_INVALID_ACTION, "Unable to release packet data");
+ }
}
/* if p uses extended data, free them */