]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
af-packet: cache map fd search
authorEric Leblond <eric@regit.org>
Thu, 21 Dec 2017 15:52:37 +0000 (16:52 +0100)
committerEric Leblond <eric@regit.org>
Tue, 6 Feb 2018 15:58:18 +0000 (16:58 +0100)
src/source-af-packet.c
src/source-af-packet.h

index 6936391bc2f972e3f8f5c6196cdaca39a7f4865d..2fcad222387c6ac39afed1c19b0d1660b8a74c16 100644 (file)
@@ -49,6 +49,7 @@
 #include "util-cpu.h"
 #include "util-debug.h"
 #include "util-device.h"
+#include "util-ebpf.h"
 #include "util-error.h"
 #include "util-privs.h"
 #include "util-optimize.h"
@@ -222,6 +223,11 @@ typedef struct AFPThreadVars_
     /* data link type for the thread */
     uint32_t datalink;
 
+#ifdef HAVE_PACKET_EBPF
+    int v4_map_fd;
+    int v6_map_fd;
+#endif
+
     unsigned int frame_offset;
 
     ChecksumValidationMode checksum_mode;
@@ -620,9 +626,17 @@ static int AFPRead(AFPThreadVars *ptv)
     PKT_SET_SRC(p, PKT_SRC_WIRE);
     if (ptv->flags & AFP_BYPASS) {
         p->BypassPacketsFlow = AFPBypassCallback;
+#ifdef HAVE_PACKET_EBPF
+        p->afp_v.v4_map_fd = ptv->v4_map_fd;
+        p->afp_v.v6_map_fd = ptv->v6_map_fd;
+#endif
     }
     if (ptv->flags & AFP_XDPBYPASS) {
         p->BypassPacketsFlow = AFPXDPBypassCallback;
+#ifdef HAVE_PACKET_EBPF
+        p->afp_v.v4_map_fd = ptv->v4_map_fd;
+        p->afp_v.v6_map_fd = ptv->v6_map_fd;
+#endif
     }
 
     /* get timestamp of packet via ioctl */
@@ -895,9 +909,17 @@ static int AFPReadFromRing(AFPThreadVars *ptv)
         PKT_SET_SRC(p, PKT_SRC_WIRE);
         if (ptv->flags & AFP_BYPASS) {
             p->BypassPacketsFlow = AFPBypassCallback;
+#ifdef HAVE_PACKET_EBPF
+            p->afp_v.v4_map_fd = ptv->v4_map_fd;    
+            p->afp_v.v6_map_fd = ptv->v6_map_fd;    
+#endif
         }
         if (ptv->flags & AFP_XDPBYPASS) {
             p->BypassPacketsFlow = AFPXDPBypassCallback;
+#ifdef HAVE_PACKET_EBPF
+            p->afp_v.v4_map_fd = ptv->v4_map_fd;    
+            p->afp_v.v6_map_fd = ptv->v6_map_fd;    
+#endif
         }
 
         /* Suricata will treat packet so telling it is busy, this
@@ -945,6 +967,7 @@ static int AFPReadFromRing(AFPThreadVars *ptv)
                 SCReturnInt(AFP_FAILURE);
             }
         }
+
         /* Timestamp */
         p->ts.tv_sec = h.h2->tp_sec;
         p->ts.tv_usec = h.h2->tp_nsec/1000;
@@ -1013,9 +1036,17 @@ static inline int AFPParsePacketV3(AFPThreadVars *ptv, struct tpacket_block_desc
     PKT_SET_SRC(p, PKT_SRC_WIRE);
     if (ptv->flags & AFP_BYPASS) {
         p->BypassPacketsFlow = AFPBypassCallback;
+#ifdef HAVE_PACKET_EBPF
+        p->afp_v.v4_map_fd = ptv->v4_map_fd;    
+        p->afp_v.v6_map_fd = ptv->v6_map_fd;    
+#endif
     }
     if (ptv->flags & AFP_XDPBYPASS) {
         p->BypassPacketsFlow = AFPXDPBypassCallback;
+#ifdef HAVE_PACKET_EBPF
+        p->afp_v.v4_map_fd = ptv->v4_map_fd;    
+        p->afp_v.v6_map_fd = ptv->v6_map_fd;    
+#endif
     }
 
     ptv->pkts++;
@@ -2281,13 +2312,7 @@ static int AFPBypassCallback(Packet *p)
         inittime = curtime.tv_sec * 1000000000;
     }
     if (PKT_IS_IPV4(p)) {
-        /* FIXME cache this and handle error at cache time*/
-        int mapd = EBPFGetMapFDByName("flow_table_v4");
-        if (mapd == -1) {
-            SCLogNotice("Can't find eBPF map fd for '%s'", "flow_table_v4");
-            return 0;
-        }
-        /* FIXME error handling */
+        SCLogDebug("add an IPv4");
         struct flowv4_keys key = {};
         key.src = htonl(GET_IPV4_SRC_ADDR_U32(p));
         key.dst = htonl(GET_IPV4_DST_ADDR_U32(p));
@@ -2295,14 +2320,14 @@ static int AFPBypassCallback(Packet *p)
         key.port16[1] = GET_TCP_DST_PORT(p);
 
         key.ip_proto = IPV4_GET_IPPROTO(p);
-        if (AFPInsertHalfFlow(mapd, &key, inittime) == 0) {
+        if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, &key, inittime) == 0) {
             return 0;
         }
         key.src = htonl(GET_IPV4_DST_ADDR_U32(p));
         key.dst = htonl(GET_IPV4_SRC_ADDR_U32(p));
         key.port16[0] = GET_TCP_DST_PORT(p);
         key.port16[1] = GET_TCP_SRC_PORT(p);
-        if (AFPInsertHalfFlow(mapd, &key, inittime) == 0) {
+        if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, &key, inittime) == 0) {
             return 0;
         }
         return 1;
@@ -2310,16 +2335,8 @@ static int AFPBypassCallback(Packet *p)
     /* For IPv6 case we don't handle extended header in eBPF */
     if (PKT_IS_IPV6(p) && 
         ((IPV6_GET_NH(p) == IPPROTO_TCP) || (IPV6_GET_NH(p) == IPPROTO_UDP))) {
-        /* FIXME cache this and handle error at cache time*/
-        int mapd = EBPFGetMapFDByName("flow_table_v6");
-        int i = 0;
-        if (mapd == -1) {
-            SCLogNotice("Can't find eBPF map fd for '%s'", "flow_table_v6");
-            return 0;
-        }
+        int i;
         SCLogDebug("add an IPv6");
-        /* FIXME error handling */
-        /* FIXME filter out next hdr IPV6 packets */
         struct flowv6_keys key = {};
         for (i = 0; i < 4; i++) {
             key.src[i] = ntohl(GET_IPV6_SRC_ADDR(p)[i]);
@@ -2328,7 +2345,7 @@ static int AFPBypassCallback(Packet *p)
         key.port16[0] = GET_TCP_SRC_PORT(p);
         key.port16[1] = GET_TCP_DST_PORT(p);
         key.ip_proto = IPV6_GET_NH(p);
-        if (AFPInsertHalfFlow(mapd, &key, inittime) == 0) {
+        if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, &key, inittime) == 0) {
             return 0;
         }
         for (i = 0; i < 4; i++) {
@@ -2337,7 +2354,7 @@ static int AFPBypassCallback(Packet *p)
         }
         key.port16[0] = GET_TCP_DST_PORT(p);
         key.port16[1] = GET_TCP_SRC_PORT(p);
-        if (AFPInsertHalfFlow(mapd, &key, inittime) == 0) {
+        if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, &key, inittime) == 0) {
             return 0;
         }
         return 1;
@@ -2367,13 +2384,6 @@ static int AFPXDPBypassCallback(Packet *p)
         inittime = curtime.tv_sec * 1000000000;
     }
     if (PKT_IS_IPV4(p)) {
-        /* FIXME cache this and handle error at cache time*/
-        int mapd = EBPFGetMapFDByName("flow_table_v4");
-        if (mapd == -1) {
-            SCLogNotice("Can't find eBPF map fd for '%s'", "flow_table_v4");
-            return 0;
-        }
-        /* FIXME error handling */
         struct flowv4_keys key = {};
         key.src = GET_IPV4_SRC_ADDR_U32(p);
         key.dst = GET_IPV4_DST_ADDR_U32(p);
@@ -2381,14 +2391,14 @@ static int AFPXDPBypassCallback(Packet *p)
         key.port16[0] = htons(GET_TCP_SRC_PORT(p));
         key.port16[1] = htons(GET_TCP_DST_PORT(p));
         key.ip_proto = IPV4_GET_IPPROTO(p);
-        if (AFPInsertHalfFlow(mapd, &key, inittime) == 0) {
+        if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, &key, inittime) == 0) {
             return 0;
         }
         key.src = GET_IPV4_DST_ADDR_U32(p);
         key.dst = GET_IPV4_SRC_ADDR_U32(p);
         key.port16[0] = htons(GET_TCP_DST_PORT(p));
         key.port16[1] = htons(GET_TCP_SRC_PORT(p));
-        if (AFPInsertHalfFlow(mapd, &key, inittime) == 0) {
+        if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, &key, inittime) == 0) {
             return 0;
         }
         return 1;
@@ -2396,16 +2406,8 @@ static int AFPXDPBypassCallback(Packet *p)
     /* For IPv6 case we don't handle extended header in eBPF */
     if (PKT_IS_IPV6(p) && 
         ((IPV6_GET_NH(p) == IPPROTO_TCP) || (IPV6_GET_NH(p) == IPPROTO_UDP))) {
-        /* FIXME cache this and handle error at cache time*/
-        int mapd = EBPFGetMapFDByName("flow_table_v6");
-        int i = 0;
-        if (mapd == -1) {
-            SCLogNotice("Can't find eBPF map fd for '%s'", "flow_table_v6");
-            return 0;
-        }
         SCLogDebug("add an IPv6");
-        /* FIXME error handling */
-        /* FIXME filter out next hdr IPV6 packets */
+        int i;
         struct flowv6_keys key = {};
         for (i = 0; i < 4; i++) {
             key.src[i] = GET_IPV6_SRC_ADDR(p)[i];
@@ -2414,7 +2416,7 @@ static int AFPXDPBypassCallback(Packet *p)
         key.port16[0] = htons(GET_TCP_SRC_PORT(p));
         key.port16[1] = htons(GET_TCP_DST_PORT(p));
         key.ip_proto = IPV6_GET_NH(p);
-        if (AFPInsertHalfFlow(mapd, &key, inittime) == 0) {
+        if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, &key, inittime) == 0) {
             return 0;
         }
         for (i = 0; i < 4; i++) {
@@ -2423,7 +2425,7 @@ static int AFPXDPBypassCallback(Packet *p)
         }
         key.port16[0] = htons(GET_TCP_DST_PORT(p));
         key.port16[1] = htons(GET_TCP_SRC_PORT(p));
-        if (AFPInsertHalfFlow(mapd, &key, inittime) == 0) {
+        if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, &key, inittime) == 0) {
             return 0;
         }
         return 1;
@@ -2499,6 +2501,19 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, const void *initdata, void **data)
     ptv->ebpf_filter_fd = afpconfig->ebpf_filter_fd;
     ptv->xdp_mode = afpconfig->xdp_mode;
 
+#ifdef HAVE_PACKET_EBPF
+    if (ptv->flags & (AFP_BYPASS|AFP_XDPBYPASS)) {
+        ptv->v4_map_fd = EBPFGetMapFDByName("flow_table_v4");
+        if (ptv->v4_map_fd == -1) {
+            SCLogError(SC_ERR_INVALID_VALUE, "Can't find eBPF map fd for '%s'", "flow_table_v4");
+        }
+        ptv->v6_map_fd = EBPFGetMapFDByName("flow_table_v6");
+        if (ptv->v6_map_fd  == -1) {
+            SCLogError(SC_ERR_INVALID_VALUE, "Can't find eBPF map fd for '%s'", "flow_table_v6");
+        }
+    }
+#endif
+
 #ifdef PACKET_STATISTICS
     ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets",
             ptv->tv);
index 30cb029be5507cd985fd2e828eeb4316273a5071..2beae12b5004511e63d374c3249386340810064a 100644 (file)
@@ -135,6 +135,8 @@ typedef struct AFPPacketVars_
      */
     AFPPeer *mpeer;
     uint8_t copy_mode;
+    int v4_map_fd;
+    int v6_map_fd;
 } AFPPacketVars;
 
 #define AFPV_CLEANUP(afpv) do {           \