From d65f45856cd596dee61d30435ba17fbd7bb4c100 Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Thu, 21 Dec 2017 16:52:37 +0100 Subject: [PATCH] af-packet: cache map fd search --- src/source-af-packet.c | 95 ++++++++++++++++++++++++------------------ src/source-af-packet.h | 2 + 2 files changed, 57 insertions(+), 40 deletions(-) diff --git a/src/source-af-packet.c b/src/source-af-packet.c index 6936391bc2..2fcad22238 100644 --- a/src/source-af-packet.c +++ b/src/source-af-packet.c @@ -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); diff --git a/src/source-af-packet.h b/src/source-af-packet.h index 30cb029be5..2beae12b50 100644 --- a/src/source-af-packet.h +++ b/src/source-af-packet.h @@ -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 { \ -- 2.47.2