diff --git a/src/source-af-packet.c b/src/source-af-packet.c index d770050c00..d87776f56c 100644 --- a/src/source-af-packet.c +++ b/src/source-af-packet.c @@ -2299,7 +2299,7 @@ static int AFPInsertHalfFlow(int mapd, void *key, uint32_t hash, uint64_t pkts_cnt, uint64_t bytes_cnt, unsigned int nr_cpus) { - struct pair value[nr_cpus]; + BPF_DECLARE_PERCPU(struct pair, value, nr_cpus); unsigned int i; if (mapd == -1) { @@ -2310,12 +2310,13 @@ static int AFPInsertHalfFlow(int mapd, void *key, uint32_t hash, * is not duplicating the data on each CPU by itself. We set the first entry to * the actual flow pkts and bytes count as we need to continue from actual point * to detect an absence of packets in the future. */ - value[0].packets = pkts_cnt; - value[0].bytes = bytes_cnt; - value[0].hash = hash; + BPF_PERCPU(value,0).packets = pkts_cnt; + BPF_PERCPU(value,0).bytes = bytes_cnt; + BPF_PERCPU(value,0).hash = hash; for (i = 1; i < nr_cpus; i++) { - value[i].packets = 0; - value[i].bytes = 0; + BPF_PERCPU(value, i).packets = 0; + BPF_PERCPU(value, i).bytes = 0; + BPF_PERCPU(value, i).hash = hash; } if (bpf_map_update_elem(mapd, key, value, BPF_NOEXIST) != 0) { switch (errno) { diff --git a/src/util-ebpf.c b/src/util-ebpf.c index 7774b25163..4a5f25bd0a 100644 --- a/src/util-ebpf.c +++ b/src/util-ebpf.c @@ -560,7 +560,7 @@ static int EBPFForEachFlowV4Table(LiveDevice *dev, const char *name, pkts_cnt = 0; /* We use a per CPU structure so we will get a array of values. But if nr_cpus * is 1 then we have a global hash. */ - struct pair values_array[tcfg->cpus_count]; + BPF_DECLARE_PERCPU(struct pair, values_array, tcfg->cpus_count); memset(values_array, 0, sizeof(values_array)); int res = bpf_map_lookup_elem(mapfd, &next_key, values_array); if (res < 0) { @@ -572,9 +572,10 @@ static int EBPFForEachFlowV4Table(LiveDevice *dev, const char *name, for (i = 0; i < tcfg->cpus_count; i++) { /* let's start accumulating value so we can compute the counters */ SCLogDebug("%d: Adding pkts %lu bytes %lu", i, - values_array[i].packets, values_array[i].bytes); - pkts_cnt += values_array[i].packets; - bytes_cnt += values_array[i].bytes; + BPF_PERCPU(values_array, i).packets, + BPF_PERCPU(values_array, i).bytes); + pkts_cnt += BPF_PERCPU(values_array, i).packets; + bytes_cnt += BPF_PERCPU(values_array, i).bytes; } /* Get the corresponding Flow in the Flow table to compare and update * its counters and lastseen if needed */ @@ -600,7 +601,8 @@ static int EBPFForEachFlowV4Table(LiveDevice *dev, const char *name, flow_key.vlan_id[1] = next_key.vlan_id[1]; flow_key.proto = next_key.ip_proto; flow_key.recursion_level = 0; - pkts_cnt = EBPFOpFlowForKey(flowstats, &flow_key, values_array[0].hash, + pkts_cnt = EBPFOpFlowForKey(flowstats, &flow_key, + BPF_PERCPU(values_array, 0).hash, ctime, pkts_cnt, bytes_cnt); if (pkts_cnt > 0) { found = 1; @@ -656,7 +658,7 @@ static int EBPFForEachFlowV6Table(LiveDevice *dev, const char *name, pkts_cnt = 0; /* We use a per CPU structure so we will get a array of values. But if nr_cpus * is 1 then we have a global hash. */ - struct pair values_array[tcfg->cpus_count]; + BPF_DECLARE_PERCPU(struct pair, values_array, tcfg->cpus_count); memset(values_array, 0, sizeof(values_array)); int res = bpf_map_lookup_elem(mapfd, &next_key, values_array); if (res < 0) { @@ -667,9 +669,10 @@ static int EBPFForEachFlowV6Table(LiveDevice *dev, const char *name, for (i = 0; i < tcfg->cpus_count; i++) { /* let's start accumulating value so we can compute the counters */ SCLogDebug("%d: Adding pkts %lu bytes %lu", i, - values_array[i].packets, values_array[i].bytes); - pkts_cnt += values_array[i].packets; - bytes_cnt += values_array[i].bytes; + BPF_PERCPU(values_array, i).packets, + BPF_PERCPU(values_array, i).bytes); + pkts_cnt += BPF_PERCPU(values_array, i).packets; + bytes_cnt += BPF_PERCPU(values_array, i).bytes; } /* Get the corresponding Flow in the Flow table to compare and update * its counters and lastseen if needed */ @@ -695,7 +698,7 @@ static int EBPFForEachFlowV6Table(LiveDevice *dev, const char *name, flow_key.vlan_id[1] = next_key.vlan_id[1]; flow_key.proto = next_key.ip_proto; flow_key.recursion_level = 0; - pkts_cnt = EBPFOpFlowForKey(flowstats, &flow_key, values_array[0].hash, + pkts_cnt = EBPFOpFlowForKey(flowstats, &flow_key, BPF_PERCPU(values_array, 0).hash, ctime, pkts_cnt, bytes_cnt); if (pkts_cnt > 0) { found = 1; diff --git a/src/util-ebpf.h b/src/util-ebpf.h index c66c1d9e2e..078870aa4b 100644 --- a/src/util-ebpf.h +++ b/src/util-ebpf.h @@ -88,6 +88,14 @@ int EBPFUpdateFlow(Flow *f, Packet *p, void *data); TmEcode EBPFGetBypassedStats(json_t *cmd, json_t *answer, void *data); #endif +#define __bpf_percpu_val_align __attribute__((__aligned__(8))) + +#define BPF_DECLARE_PERCPU(type, name, nr_cpus) \ + struct { type v; /* padding */ } __bpf_percpu_val_align \ + name[nr_cpus] +#define BPF_PERCPU(name, cpu) name[(cpu)].v + + #endif #endif