af-packet: detect availability of tpacket_v3

If TPACKET_V3 is not defined then it is not available and we should
not build anything related to tpacket_v3. This will allow us to
activate it dy default and fallback to v2 if not available.
pull/2091/head
Eric Leblond 9 years ago committed by Victor Julien
parent f5c2019167
commit c2d0d93806

@ -1192,6 +1192,11 @@
AC_DEFINE([HAVE_PACKET_FANOUT],[1],[Recent packet fanout support is available]), AC_DEFINE([HAVE_PACKET_FANOUT],[1],[Recent packet fanout support is available]),
[], [],
[[#include <linux/if_packet.h>]]) [[#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 # Netmap support

@ -231,13 +231,19 @@ void *ParseAFPConfig(const char *iface)
(void)ConfGetChildValueBoolWithDefault(if_root, if_default, "tpacket-v3", (int *)&boolval); (void)ConfGetChildValueBoolWithDefault(if_root, if_default, "tpacket-v3", (int *)&boolval);
if (boolval) { if (boolval) {
if (strcasecmp(RunmodeGetActive(), "workers") == 0) { if (strcasecmp(RunmodeGetActive(), "workers") == 0) {
#ifdef HAVE_TPACKET_V3
SCLogInfo("Enabling tpacket v3 capture on iface %s", SCLogInfo("Enabling tpacket v3 capture on iface %s",
aconf->iface); aconf->iface);
aconf->flags |= AFP_TPACKET_V3|AFP_RING_MODE; 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 { } else {
SCLogError(SC_ERR_RUNMODE, SCLogError(SC_ERR_RUNMODE,
"tpacket v3 is only implemented for 'workers' running mode." "tpacket v3 is only implemented for 'workers' running mode."
" Switching to tpacket v2."); " Switching to tpacket v2.");
aconf->flags |= AFP_RING_MODE;
} }
} }
(void)ConfGetChildValueBoolWithDefault(if_root, if_default, "use-emergency-flush", (int *)&boolval); (void)ConfGetChildValueBoolWithDefault(if_root, if_default, "use-emergency-flush", (int *)&boolval);

@ -179,7 +179,9 @@ enum {
union thdr { union thdr {
struct tpacket2_hdr *h2; struct tpacket2_hdr *h2;
#ifdef HAVE_TPACKET_V3
struct tpacket3_hdr *h3; struct tpacket3_hdr *h3;
#endif
void *raw; void *raw;
}; };
@ -249,7 +251,9 @@ typedef struct AFPThreadVars_
union { union {
struct tpacket_req req; struct tpacket_req req;
#ifdef HAVE_TPACKET_V3
struct tpacket_req3 req3; struct tpacket_req3 req3;
#endif
}; };
char iface[AFP_IFACE_NAME_LENGTH]; char iface[AFP_IFACE_NAME_LENGTH];
@ -1002,6 +1006,7 @@ static inline int AFPWalkBlock(AFPThreadVars *ptv, struct tpacket_block_desc *pb
*/ */
int AFPReadFromRingV3(AFPThreadVars *ptv) int AFPReadFromRingV3(AFPThreadVars *ptv)
{ {
#ifdef HAVE_TPACKET_V3
struct tpacket_block_desc *pbd; struct tpacket_block_desc *pbd;
/* Loop till we have packets available */ /* Loop till we have packets available */
@ -1030,7 +1035,7 @@ int AFPReadFromRingV3(AFPThreadVars *ptv)
SCReturnInt(AFP_READ_OK); SCReturnInt(AFP_READ_OK);
} }
} }
#endif
SCReturnInt(AFP_READ_OK); SCReturnInt(AFP_READ_OK);
} }
@ -1554,6 +1559,7 @@ frame size: TPACKET_ALIGN(snaplen + TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + siz
return 1; return 1;
} }
#ifdef HAVE_TPACKET_V3
static int AFPComputeRingParamsV3(AFPThreadVars *ptv) static int AFPComputeRingParamsV3(AFPThreadVars *ptv)
{ {
ptv->req3.tp_block_size = ptv->block_size; ptv->req3.tp_block_size = ptv->block_size;
@ -1592,6 +1598,7 @@ static int AFPComputeRingParamsV3(AFPThreadVars *ptv)
); );
return 1; return 1;
} }
#endif
static int AFPSetupRing(AFPThreadVars *ptv, char *devname) static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
{ {
@ -1602,11 +1609,15 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
int order; int order;
int r, mmap_flag; int r, mmap_flag;
#ifdef HAVE_TPACKET_V3
if (ptv->flags & AFP_TPACKET_V3) { if (ptv->flags & AFP_TPACKET_V3) {
val = TPACKET_V3; val = TPACKET_V3;
} else { } else {
#endif
val = TPACKET_V2; val = TPACKET_V2;
#ifdef HAVE_TPACKET_V3
} }
#endif
if (getsockopt(ptv->socket, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0) { if (getsockopt(ptv->socket, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0) {
if (errno == ENOPROTOOPT) { if (errno == ENOPROTOOPT) {
if (ptv->flags & AFP_TPACKET_V3) { if (ptv->flags & AFP_TPACKET_V3) {
@ -1635,6 +1646,7 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
} }
/* Allocate RX ring */ /* Allocate RX ring */
#ifdef HAVE_TPACKET_V3
if (ptv->flags & AFP_TPACKET_V3) { if (ptv->flags & AFP_TPACKET_V3) {
if (AFPComputeRingParamsV3(ptv) != 1) { if (AFPComputeRingParamsV3(ptv) != 1) {
return AFP_FATAL_ERROR; return AFP_FATAL_ERROR;
@ -1650,6 +1662,7 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
return AFP_FATAL_ERROR; return AFP_FATAL_ERROR;
} }
} else { } else {
#endif
for (order = AFP_BLOCK_SIZE_DEFAULT_ORDER; order >= 0; order--) { for (order = AFP_BLOCK_SIZE_DEFAULT_ORDER; order >= 0; order--) {
if (AFPComputeRingParams(ptv, order) != 1) { if (AFPComputeRingParams(ptv, order) != 1) {
SCLogInfo("Ring parameter are incorrect. Please correct the devel"); SCLogInfo("Ring parameter are incorrect. Please correct the devel");
@ -1680,14 +1693,20 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
devname); devname);
return AFP_FATAL_ERROR; return AFP_FATAL_ERROR;
} }
#ifdef HAVE_TPACKET_V3
} }
#endif
/* Allocate the Ring */ /* Allocate the Ring */
#ifdef HAVE_TPACKET_V3
if (ptv->flags & AFP_TPACKET_V3) { if (ptv->flags & AFP_TPACKET_V3) {
ring_buflen = ptv->req3.tp_block_nr * ptv->req3.tp_block_size; ring_buflen = ptv->req3.tp_block_nr * ptv->req3.tp_block_size;
} else { } else {
#endif
ring_buflen = ptv->req.tp_block_nr * ptv->req.tp_block_size; ring_buflen = ptv->req.tp_block_nr * ptv->req.tp_block_size;
#ifdef HAVE_TPACKET_V3
} }
#endif
mmap_flag = MAP_SHARED; mmap_flag = MAP_SHARED;
if (ptv->flags & AFP_MMAP_LOCKED) if (ptv->flags & AFP_MMAP_LOCKED)
mmap_flag |= MAP_LOCKED; mmap_flag |= MAP_LOCKED;
@ -1697,6 +1716,7 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
SCLogError(SC_ERR_MEM_ALLOC, "Unable to mmap"); SCLogError(SC_ERR_MEM_ALLOC, "Unable to mmap");
goto mmap_err; goto mmap_err;
} }
#ifdef HAVE_TPACKET_V3
if (ptv->flags & AFP_TPACKET_V3) { if (ptv->flags & AFP_TPACKET_V3) {
ptv->ring_v3 = SCMalloc(ptv->req3.tp_block_nr * sizeof(*ptv->ring_v3)); ptv->ring_v3 = SCMalloc(ptv->req3.tp_block_nr * sizeof(*ptv->ring_v3));
if (!ptv->ring_v3) { if (!ptv->ring_v3) {
@ -1708,6 +1728,7 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
ptv->ring_v3[i].iov_len = ptv->req3.tp_block_size; ptv->ring_v3[i].iov_len = ptv->req3.tp_block_size;
} }
} else { } else {
#endif
/* allocate a ring for each frame header pointer*/ /* allocate a ring for each frame header pointer*/
ptv->ring_v2 = SCMalloc(ptv->req.tp_frame_nr * sizeof (union thdr *)); ptv->ring_v2 = SCMalloc(ptv->req.tp_frame_nr * sizeof (union thdr *));
if (ptv->ring_v2 == NULL) { if (ptv->ring_v2 == NULL) {
@ -1726,7 +1747,9 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
} }
} }
ptv->frame_offset = 0; ptv->frame_offset = 0;
#ifdef HAVE_TPACKET_V3
} }
#endif
return 0; return 0;

Loading…
Cancel
Save