af-packet: cache map fd search

pull/3221/head
Eric Leblond 9 years ago
parent 17a32bdaa0
commit d65f45856c

@ -49,6 +49,7 @@
#include "util-cpu.h" #include "util-cpu.h"
#include "util-debug.h" #include "util-debug.h"
#include "util-device.h" #include "util-device.h"
#include "util-ebpf.h"
#include "util-error.h" #include "util-error.h"
#include "util-privs.h" #include "util-privs.h"
#include "util-optimize.h" #include "util-optimize.h"
@ -222,6 +223,11 @@ typedef struct AFPThreadVars_
/* data link type for the thread */ /* data link type for the thread */
uint32_t datalink; uint32_t datalink;
#ifdef HAVE_PACKET_EBPF
int v4_map_fd;
int v6_map_fd;
#endif
unsigned int frame_offset; unsigned int frame_offset;
ChecksumValidationMode checksum_mode; ChecksumValidationMode checksum_mode;
@ -620,9 +626,17 @@ static int AFPRead(AFPThreadVars *ptv)
PKT_SET_SRC(p, PKT_SRC_WIRE); PKT_SET_SRC(p, PKT_SRC_WIRE);
if (ptv->flags & AFP_BYPASS) { if (ptv->flags & AFP_BYPASS) {
p->BypassPacketsFlow = AFPBypassCallback; 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) { if (ptv->flags & AFP_XDPBYPASS) {
p->BypassPacketsFlow = AFPXDPBypassCallback; 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 */ /* get timestamp of packet via ioctl */
@ -895,9 +909,17 @@ static int AFPReadFromRing(AFPThreadVars *ptv)
PKT_SET_SRC(p, PKT_SRC_WIRE); PKT_SET_SRC(p, PKT_SRC_WIRE);
if (ptv->flags & AFP_BYPASS) { if (ptv->flags & AFP_BYPASS) {
p->BypassPacketsFlow = AFPBypassCallback; 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) { if (ptv->flags & AFP_XDPBYPASS) {
p->BypassPacketsFlow = AFPXDPBypassCallback; 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 /* Suricata will treat packet so telling it is busy, this
@ -945,6 +967,7 @@ static int AFPReadFromRing(AFPThreadVars *ptv)
SCReturnInt(AFP_FAILURE); SCReturnInt(AFP_FAILURE);
} }
} }
/* Timestamp */ /* Timestamp */
p->ts.tv_sec = h.h2->tp_sec; p->ts.tv_sec = h.h2->tp_sec;
p->ts.tv_usec = h.h2->tp_nsec/1000; 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); PKT_SET_SRC(p, PKT_SRC_WIRE);
if (ptv->flags & AFP_BYPASS) { if (ptv->flags & AFP_BYPASS) {
p->BypassPacketsFlow = AFPBypassCallback; 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) { if (ptv->flags & AFP_XDPBYPASS) {
p->BypassPacketsFlow = AFPXDPBypassCallback; 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++; ptv->pkts++;
@ -2281,13 +2312,7 @@ static int AFPBypassCallback(Packet *p)
inittime = curtime.tv_sec * 1000000000; inittime = curtime.tv_sec * 1000000000;
} }
if (PKT_IS_IPV4(p)) { if (PKT_IS_IPV4(p)) {
/* FIXME cache this and handle error at cache time*/ SCLogDebug("add an IPv4");
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 = {}; struct flowv4_keys key = {};
key.src = htonl(GET_IPV4_SRC_ADDR_U32(p)); key.src = htonl(GET_IPV4_SRC_ADDR_U32(p));
key.dst = htonl(GET_IPV4_DST_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.port16[1] = GET_TCP_DST_PORT(p);
key.ip_proto = IPV4_GET_IPPROTO(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; return 0;
} }
key.src = htonl(GET_IPV4_DST_ADDR_U32(p)); key.src = htonl(GET_IPV4_DST_ADDR_U32(p));
key.dst = htonl(GET_IPV4_SRC_ADDR_U32(p)); key.dst = htonl(GET_IPV4_SRC_ADDR_U32(p));
key.port16[0] = GET_TCP_DST_PORT(p); key.port16[0] = GET_TCP_DST_PORT(p);
key.port16[1] = GET_TCP_SRC_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 0;
} }
return 1; return 1;
@ -2310,16 +2335,8 @@ static int AFPBypassCallback(Packet *p)
/* For IPv6 case we don't handle extended header in eBPF */ /* For IPv6 case we don't handle extended header in eBPF */
if (PKT_IS_IPV6(p) && if (PKT_IS_IPV6(p) &&
((IPV6_GET_NH(p) == IPPROTO_TCP) || (IPV6_GET_NH(p) == IPPROTO_UDP))) { ((IPV6_GET_NH(p) == IPPROTO_TCP) || (IPV6_GET_NH(p) == IPPROTO_UDP))) {
/* FIXME cache this and handle error at cache time*/ int i;
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"); SCLogDebug("add an IPv6");
/* FIXME error handling */
/* FIXME filter out next hdr IPV6 packets */
struct flowv6_keys key = {}; struct flowv6_keys key = {};
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
key.src[i] = ntohl(GET_IPV6_SRC_ADDR(p)[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[0] = GET_TCP_SRC_PORT(p);
key.port16[1] = GET_TCP_DST_PORT(p); key.port16[1] = GET_TCP_DST_PORT(p);
key.ip_proto = IPV6_GET_NH(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; return 0;
} }
for (i = 0; i < 4; i++) { 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[0] = GET_TCP_DST_PORT(p);
key.port16[1] = GET_TCP_SRC_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 0;
} }
return 1; return 1;
@ -2367,13 +2384,6 @@ static int AFPXDPBypassCallback(Packet *p)
inittime = curtime.tv_sec * 1000000000; inittime = curtime.tv_sec * 1000000000;
} }
if (PKT_IS_IPV4(p)) { 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 = {}; struct flowv4_keys key = {};
key.src = GET_IPV4_SRC_ADDR_U32(p); key.src = GET_IPV4_SRC_ADDR_U32(p);
key.dst = GET_IPV4_DST_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[0] = htons(GET_TCP_SRC_PORT(p));
key.port16[1] = htons(GET_TCP_DST_PORT(p)); key.port16[1] = htons(GET_TCP_DST_PORT(p));
key.ip_proto = IPV4_GET_IPPROTO(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; return 0;
} }
key.src = GET_IPV4_DST_ADDR_U32(p); key.src = GET_IPV4_DST_ADDR_U32(p);
key.dst = GET_IPV4_SRC_ADDR_U32(p); key.dst = GET_IPV4_SRC_ADDR_U32(p);
key.port16[0] = htons(GET_TCP_DST_PORT(p)); key.port16[0] = htons(GET_TCP_DST_PORT(p));
key.port16[1] = htons(GET_TCP_SRC_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 0;
} }
return 1; return 1;
@ -2396,16 +2406,8 @@ static int AFPXDPBypassCallback(Packet *p)
/* For IPv6 case we don't handle extended header in eBPF */ /* For IPv6 case we don't handle extended header in eBPF */
if (PKT_IS_IPV6(p) && if (PKT_IS_IPV6(p) &&
((IPV6_GET_NH(p) == IPPROTO_TCP) || (IPV6_GET_NH(p) == IPPROTO_UDP))) { ((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"); SCLogDebug("add an IPv6");
/* FIXME error handling */ int i;
/* FIXME filter out next hdr IPV6 packets */
struct flowv6_keys key = {}; struct flowv6_keys key = {};
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
key.src[i] = GET_IPV6_SRC_ADDR(p)[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[0] = htons(GET_TCP_SRC_PORT(p));
key.port16[1] = htons(GET_TCP_DST_PORT(p)); key.port16[1] = htons(GET_TCP_DST_PORT(p));
key.ip_proto = IPV6_GET_NH(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; return 0;
} }
for (i = 0; i < 4; i++) { 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[0] = htons(GET_TCP_DST_PORT(p));
key.port16[1] = htons(GET_TCP_SRC_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 0;
} }
return 1; return 1;
@ -2499,6 +2501,19 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, const void *initdata, void **data)
ptv->ebpf_filter_fd = afpconfig->ebpf_filter_fd; ptv->ebpf_filter_fd = afpconfig->ebpf_filter_fd;
ptv->xdp_mode = afpconfig->xdp_mode; 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 #ifdef PACKET_STATISTICS
ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets", ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets",
ptv->tv); ptv->tv);

@ -135,6 +135,8 @@ typedef struct AFPPacketVars_
*/ */
AFPPeer *mpeer; AFPPeer *mpeer;
uint8_t copy_mode; uint8_t copy_mode;
int v4_map_fd;
int v6_map_fd;
} AFPPacketVars; } AFPPacketVars;
#define AFPV_CLEANUP(afpv) do { \ #define AFPV_CLEANUP(afpv) do { \

Loading…
Cancel
Save