AC_DEFINE([HAVE_PACKET_FANOUT],[1],[Recent packet fanout support is available]),
[],
[[#include <linux/if_packet.h>]])
+ AC_CHECK_DECL([TPACKET_V3],
+ AC_DEFINE([HAVE_TPACKET_V3],[1],[AF_PACKET tpcket_v3 support is available]),
+ [],
+ [[#include <sys/socket.h>
+ #include <linux/if_packet.h>]])
])
# Netmap support
(void)ConfGetChildValueBoolWithDefault(if_root, if_default, "tpacket-v3", (int *)&boolval);
if (boolval) {
if (strcasecmp(RunmodeGetActive(), "workers") == 0) {
+#ifdef HAVE_TPACKET_V3
SCLogInfo("Enabling tpacket v3 capture on iface %s",
aconf->iface);
aconf->flags |= AFP_TPACKET_V3|AFP_RING_MODE;
+#else
+ SCLogNotice("System too old for tpacket v3 switching to v2");
+ aconf->flags |= AFP_RING_MODE;
+#endif
} else {
SCLogError(SC_ERR_RUNMODE,
"tpacket v3 is only implemented for 'workers' running mode."
" Switching to tpacket v2.");
+ aconf->flags |= AFP_RING_MODE;
}
}
(void)ConfGetChildValueBoolWithDefault(if_root, if_default, "use-emergency-flush", (int *)&boolval);
union thdr {
struct tpacket2_hdr *h2;
+#ifdef HAVE_TPACKET_V3
struct tpacket3_hdr *h3;
+#endif
void *raw;
};
union {
struct tpacket_req req;
+#ifdef HAVE_TPACKET_V3
struct tpacket_req3 req3;
+#endif
};
char iface[AFP_IFACE_NAME_LENGTH];
*/
int AFPReadFromRingV3(AFPThreadVars *ptv)
{
+#ifdef HAVE_TPACKET_V3
struct tpacket_block_desc *pbd;
/* Loop till we have packets available */
SCReturnInt(AFP_READ_OK);
}
}
-
+#endif
SCReturnInt(AFP_READ_OK);
}
return 1;
}
+#ifdef HAVE_TPACKET_V3
static int AFPComputeRingParamsV3(AFPThreadVars *ptv)
{
ptv->req3.tp_block_size = ptv->block_size;
);
return 1;
}
+#endif
static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
{
int order;
int r, mmap_flag;
+#ifdef HAVE_TPACKET_V3
if (ptv->flags & AFP_TPACKET_V3) {
val = TPACKET_V3;
} else {
+#endif
val = TPACKET_V2;
+#ifdef HAVE_TPACKET_V3
}
+#endif
if (getsockopt(ptv->socket, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0) {
if (errno == ENOPROTOOPT) {
if (ptv->flags & AFP_TPACKET_V3) {
}
/* Allocate RX ring */
+#ifdef HAVE_TPACKET_V3
if (ptv->flags & AFP_TPACKET_V3) {
if (AFPComputeRingParamsV3(ptv) != 1) {
return AFP_FATAL_ERROR;
return AFP_FATAL_ERROR;
}
} else {
+#endif
for (order = AFP_BLOCK_SIZE_DEFAULT_ORDER; order >= 0; order--) {
if (AFPComputeRingParams(ptv, order) != 1) {
SCLogInfo("Ring parameter are incorrect. Please correct the devel");
devname);
return AFP_FATAL_ERROR;
}
+#ifdef HAVE_TPACKET_V3
}
+#endif
/* Allocate the Ring */
+#ifdef HAVE_TPACKET_V3
if (ptv->flags & AFP_TPACKET_V3) {
ring_buflen = ptv->req3.tp_block_nr * ptv->req3.tp_block_size;
} else {
+#endif
ring_buflen = ptv->req.tp_block_nr * ptv->req.tp_block_size;
+#ifdef HAVE_TPACKET_V3
}
+#endif
mmap_flag = MAP_SHARED;
if (ptv->flags & AFP_MMAP_LOCKED)
mmap_flag |= MAP_LOCKED;
SCLogError(SC_ERR_MEM_ALLOC, "Unable to mmap");
goto mmap_err;
}
+#ifdef HAVE_TPACKET_V3
if (ptv->flags & AFP_TPACKET_V3) {
ptv->ring_v3 = SCMalloc(ptv->req3.tp_block_nr * sizeof(*ptv->ring_v3));
if (!ptv->ring_v3) {
ptv->ring_v3[i].iov_len = ptv->req3.tp_block_size;
}
} else {
+#endif
/* allocate a ring for each frame header pointer*/
ptv->ring_v2 = SCMalloc(ptv->req.tp_frame_nr * sizeof (union thdr *));
if (ptv->ring_v2 == NULL) {
}
}
ptv->frame_offset = 0;
+#ifdef HAVE_TPACKET_V3
}
+#endif
return 0;