From: Eric Leblond Date: Sun, 17 Dec 2017 21:09:23 +0000 (+0100) Subject: af-packet: fix bypassing of IPv6 X-Git-Tag: suricata-4.1.0-beta1~213 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=17a32bdaa0d836e7e33c848492d2becf9f850df7;p=thirdparty%2Fsuricata.git af-packet: fix bypassing of IPv6 Also misc fixes. --- diff --git a/ebpf/xdp_filter.c b/ebpf/xdp_filter.c index 19f7b1e960..ac9aaeefd6 100644 --- a/ebpf/xdp_filter.c +++ b/ebpf/xdp_filter.c @@ -144,10 +144,13 @@ static int __always_inline filter_ipv4(void *data, __u64 nh_off, void *data_end) #if 0 char fmt[] = "Found flow v4: %u %d -> %d\n"; bpf_trace_printk(fmt, sizeof(fmt), tuple.src, sport, dport); + char fmt[] = "Data: t:%lu p:%lu n:%lu\n"; + bpf_trace_printk(fmt, sizeof(fmt), value->time, value->packets, value->bytes); #endif + value->time = bpf_ktime_get_ns(); value->packets++; value->bytes += data_end - data; - value->time = bpf_ktime_get_ns(); + return XDP_DROP; } return XDP_PASS; diff --git a/src/source-af-packet.c b/src/source-af-packet.c index 2ff773a9f2..6936391bc2 100644 --- a/src/source-af-packet.c +++ b/src/source-af-packet.c @@ -46,6 +46,7 @@ #include "tm-threads.h" #include "tm-threads-common.h" #include "conf.h" +#include "util-cpu.h" #include "util-debug.h" #include "util-device.h" #include "util-error.h" @@ -2230,22 +2231,29 @@ TmEcode AFPSetBPFFilter(AFPThreadVars *ptv) */ static int AFPInsertHalfFlow(int mapd, void *key, uint64_t inittime) { - /* FIXME error handling */ - struct pair value = {inittime, 0, 0}; - SCLogDebug("Inserting element in eBPF mapping"); - if (bpf_map_update_elem(mapd, key, &value, BPF_NOEXIST) != 0) { - switch (errno) { - case E2BIG: - case EEXIST: - return 0; - default: - SCLogError(SC_ERR_BPF, "Can't update eBPF map: %s (%d)", - strerror(errno), - errno); - return 0; - } + /* FIXME error handling */ + unsigned int nr_cpus = UtilCpuGetNumProcessorsConfigured(); + struct pair value[nr_cpus]; + unsigned int i; + for (i = 0; i < nr_cpus; i++) { + value[i].time = inittime; + value[i].packets = 0; + value[i].bytes = 0; + } + SCLogDebug("Inserting element in eBPF mapping: %lu", inittime); + if (bpf_map_update_elem(mapd, key, value, BPF_NOEXIST) != 0) { + switch (errno) { + case E2BIG: + case EEXIST: + return 0; + default: + SCLogError(SC_ERR_BPF, "Can't update eBPF map: %s (%d)", + strerror(errno), + errno); + return 0; } - return 1; + } + return 1; } #endif diff --git a/src/util-ebpf.c b/src/util-ebpf.c index d3d26220eb..4ec0139436 100644 --- a/src/util-ebpf.c +++ b/src/util-ebpf.c @@ -236,18 +236,21 @@ static int EBPFForEachFlowV4Table(const char *name, SCLogWarning(SC_ERR_INVALID_VALUE, "Unable to get CPU count"); return 0; } - struct pair values_array[nr_cpus]; while (bpf_map_get_next_key(mapfd, &key, &next_key) == 0) { int iret = 1; - int pkts_cnt = 0; - int bytes_cnt = 0; + uint64_t pkts_cnt = 0; + uint64_t bytes_cnt = 0; + struct pair values_array[nr_cpus]; + memset(values_array, 0, sizeof(values_array)); bpf_map_lookup_elem(mapfd, &key, values_array); for (i = 0; i < nr_cpus; i++) { int ret = FlowCallback(mapfd, &key, &values_array[i], data); if (ret) { /* no packet for the flow on this CPU, let's start accumulating value we can compute the counters */ + SCLogDebug("%d:%lu: Adding pkts %lu bytes %lu", i, values_array[i].time / 1000000000, + values_array[i].packets, values_array[i].bytes); pkts_cnt += values_array[i].packets; bytes_cnt += values_array[i].bytes; } else { @@ -258,6 +261,8 @@ static int EBPFForEachFlowV4Table(const char *name, } /* No packet seen, we discard the flow and do accounting */ if (iret) { + SCLogDebug("Got no packet for %d -> %d", key.port16[0], key.port16[1]); + SCLogDebug("Dead with pkts %lu bytes %lu", pkts_cnt, bytes_cnt); flowstats->count++; flowstats->packets += pkts_cnt; flowstats->bytes += bytes_cnt; @@ -284,12 +289,13 @@ static int EBPFForEachFlowV6Table(const char *name, SCLogWarning(SC_ERR_INVALID_VALUE, "Unable to get CPU count"); return 0; } - struct pair values_array[nr_cpus]; while (bpf_map_get_next_key(mapfd, &key, &next_key) == 0) { int iret = 1; - int pkts_cnt = 0; - int bytes_cnt = 0; + uint64_t pkts_cnt = 0; + uint64_t bytes_cnt = 0; + struct pair values_array[nr_cpus]; + memset(values_array, 0, sizeof(values_array)); bpf_map_lookup_elem(mapfd, &key, values_array); for (i = 0; i < nr_cpus; i++) { int ret = FlowCallback(mapfd, &key, &values_array[i], data);