af-packet: cache map fd search

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

@ -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);

@ -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 { \

Loading…
Cancel
Save