From: Eric Leblond Date: Wed, 17 Jan 2018 02:24:58 +0000 (+0100) Subject: util-ebpf: add bypassed counters X-Git-Tag: suricata-4.1.0-beta1~182 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=93f5b5f1e82ddc8c08e86a0a46993d8cd2fb53db;p=thirdparty%2Fsuricata.git util-ebpf: add bypassed counters Use LiveDevice bypassed counter and also add hash size counters for the v4 and v6 flow table. --- diff --git a/src/util-ebpf.c b/src/util-ebpf.c index 4bde54dedb..341efea07c 100644 --- a/src/util-ebpf.c +++ b/src/util-ebpf.c @@ -67,6 +67,8 @@ struct bpf_map_item { struct bpf_maps_info { struct bpf_map_item array[BPF_MAP_MAX_COUNT]; + SC_ATOMIC_DECLARE(uint64_t, ipv4_hash_count); + SC_ATOMIC_DECLARE(uint64_t, ipv6_hash_count); int last; }; @@ -244,6 +246,8 @@ int EBPFLoadFile(const char *iface, const char *path, const char * section, SCLogError(SC_ERR_MEM_ALLOC, "Can't allocate bpf map array"); return -1; } + SC_ATOMIC_INIT(bpf_map_data->ipv4_hash_count); + SC_ATOMIC_INIT(bpf_map_data->ipv6_hash_count); /* Store the maps in bpf_maps_info:: */ bpf_map__for_each(map, bpfobj) { @@ -382,11 +386,11 @@ static int EBPFBypassedFlowV6Timeout(int fd, struct flowv6_keys *key, * This function iterates on all the flows of the IPv4 table * looking for timeouted flow to delete from the flow table. */ -static int EBPFForEachFlowV4Table(const char *iface, const char *name, +static int EBPFForEachFlowV4Table(LiveDevice *dev, const char *name, struct flows_stats *flowstats, struct timespec *ctime) { - int mapfd = EBPFGetMapFDByName(iface, name); + int mapfd = EBPFGetMapFDByName(dev->dev, name); struct flowv4_keys key = {}, next_key; int found = 0; unsigned int i; @@ -396,10 +400,12 @@ static int EBPFForEachFlowV4Table(const char *iface, const char *name, return 0; } + uint64_t hash_cnt = 0; while (bpf_map_get_next_key(mapfd, &key, &next_key) == 0) { bool purge = true; uint64_t pkts_cnt = 0; uint64_t bytes_cnt = 0; + hash_cnt++; /* We use a per CPU structure so we will get a array of values. */ struct pair values_array[nr_cpus]; memset(values_array, 0, sizeof(values_array)); @@ -431,12 +437,18 @@ static int EBPFForEachFlowV4Table(const char *iface, const char *name, flowstats->count++; flowstats->packets += pkts_cnt; flowstats->bytes += bytes_cnt; + SC_ATOMIC_ADD(dev->bypassed, pkts_cnt); found = 1; EBPFDeleteKey(mapfd, &key); } key = next_key; } + struct bpf_maps_info *bpfdata = LiveDevGetStorageById(dev, g_livedev_storage_id); + if (bpfdata) { + SC_ATOMIC_SET(bpfdata->ipv4_hash_count, hash_cnt); + } + return found; } @@ -446,11 +458,11 @@ static int EBPFForEachFlowV4Table(const char *iface, const char *name, * This function iterates on all the flows of the IPv4 table * looking for timeouted flow to delete from the flow table. */ -static int EBPFForEachFlowV6Table(const char *iface, const char *name, +static int EBPFForEachFlowV6Table(LiveDevice *dev, const char *name, struct flows_stats *flowstats, struct timespec *ctime) { - int mapfd = EBPFGetMapFDByName(iface, name); + int mapfd = EBPFGetMapFDByName(dev->dev, name); struct flowv6_keys key = {}, next_key; int found = 0; unsigned int i; @@ -460,10 +472,12 @@ static int EBPFForEachFlowV6Table(const char *iface, const char *name, return 0; } + uint64_t hash_cnt = 0; while (bpf_map_get_next_key(mapfd, &key, &next_key) == 0) { bool purge = true; uint64_t pkts_cnt = 0; uint64_t bytes_cnt = 0; + hash_cnt++; struct pair values_array[nr_cpus]; memset(values_array, 0, sizeof(values_array)); int res = bpf_map_lookup_elem(mapfd, &key, values_array); @@ -486,12 +500,17 @@ static int EBPFForEachFlowV6Table(const char *iface, const char *name, flowstats->count++; flowstats->packets += pkts_cnt; flowstats->bytes += bytes_cnt; + SC_ATOMIC_ADD(dev->bypassed, pkts_cnt); found = 1; EBPFDeleteKey(mapfd, &key); } key = next_key; } + struct bpf_maps_info *bpfdata = LiveDevGetStorageById(dev, g_livedev_storage_id); + if (bpfdata) { + SC_ATOMIC_SET(bpfdata->ipv6_hash_count, hash_cnt); + } return found; } @@ -511,7 +530,7 @@ int EBPFCheckBypassedFlowTimeout(struct flows_stats *bypassstats, LiveDevice *ldev = NULL, *ndev; while(LiveDeviceForEach(&ldev, &ndev)) { - tcount = EBPFForEachFlowV4Table(ldev->dev, "flow_table_v4", + tcount = EBPFForEachFlowV4Table(ldev, "flow_table_v4", &l_bypassstats, curtime); if (tcount) { bypassstats->count = l_bypassstats.count; @@ -520,7 +539,7 @@ int EBPFCheckBypassedFlowTimeout(struct flows_stats *bypassstats, ret = 1; } memset(&l_bypassstats, 0, sizeof(l_bypassstats)); - tcount = EBPFForEachFlowV6Table(ldev->dev, "flow_table_v6", + tcount = EBPFForEachFlowV6Table(ldev, "flow_table_v6", &l_bypassstats, curtime); if (tcount) { bypassstats->count += l_bypassstats.count;