]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
af-packet: detect availability of tpacket_v3
authorEric Leblond <eric@regit.org>
Sat, 9 Apr 2016 14:07:23 +0000 (16:07 +0200)
committerVictor Julien <victor@inliniac.net>
Fri, 20 May 2016 10:32:40 +0000 (12:32 +0200)
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.

configure.ac
src/runmode-af-packet.c
src/source-af-packet.c

index d5719d7748ed00fffcd38c7f2983e713ab135361..e7237651a2f46bdd3b44eef06026cea5a9e66e9a 100644 (file)
             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
index 15dc03baf498784175fa2a6b7d5d3856ef513ff7..f1c3dba31641ba2434110309a94d978ae2e45718 100644 (file)
@@ -231,13 +231,19 @@ void *ParseAFPConfig(const char *iface)
     (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);
index b149de8157b117b0c45d3073d83914f7bcd2135f..a993fddd7055efd28ade728bfab4619798cd0496 100644 (file)
@@ -179,7 +179,9 @@ enum {
 
 union thdr {
     struct tpacket2_hdr *h2;
+#ifdef HAVE_TPACKET_V3
     struct tpacket3_hdr *h3;
+#endif
     void *raw;
 };
 
@@ -249,7 +251,9 @@ typedef struct AFPThreadVars_
 
     union {
         struct tpacket_req req;
+#ifdef HAVE_TPACKET_V3
         struct tpacket_req3 req3;
+#endif
     };
 
     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)
 {
+#ifdef HAVE_TPACKET_V3
     struct tpacket_block_desc *pbd;
 
     /* Loop till we have packets available */
@@ -1030,7 +1035,7 @@ int AFPReadFromRingV3(AFPThreadVars *ptv)
             SCReturnInt(AFP_READ_OK);
         }
     }
-
+#endif
     SCReturnInt(AFP_READ_OK);
 }
 
@@ -1554,6 +1559,7 @@ frame size: TPACKET_ALIGN(snaplen + TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + siz
     return 1;
 }
 
+#ifdef HAVE_TPACKET_V3
 static int AFPComputeRingParamsV3(AFPThreadVars *ptv)
 {
     ptv->req3.tp_block_size = ptv->block_size;
@@ -1592,6 +1598,7 @@ static int AFPComputeRingParamsV3(AFPThreadVars *ptv)
               );
     return 1;
 }
+#endif
 
 static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
 {
@@ -1602,11 +1609,15 @@ 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) {
@@ -1635,6 +1646,7 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
     }
 
     /* Allocate RX ring */
+#ifdef HAVE_TPACKET_V3
     if (ptv->flags & AFP_TPACKET_V3) {
         if (AFPComputeRingParamsV3(ptv) != 1) {
             return AFP_FATAL_ERROR;
@@ -1650,6 +1662,7 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
             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");
@@ -1680,14 +1693,20 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
                     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;
@@ -1697,6 +1716,7 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
         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) {
@@ -1708,6 +1728,7 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
             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) {
@@ -1726,7 +1747,9 @@ static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
             }
         }
         ptv->frame_offset = 0;
+#ifdef HAVE_TPACKET_V3
     }
+#endif
 
     return 0;