* \return false (this create function never returns true)
*/
static bool EBPFCreateFlowForKey(struct flows_stats *flowstats, LiveDevice *dev, void *key,
- FlowKey *flow_key, struct timespec *ctime,
+ size_t skey, FlowKey *flow_key, struct timespec *ctime,
uint64_t pkts_cnt, uint64_t bytes_cnt,
int mapfd, int cpus_count)
{
if (f == NULL)
return false;
- FlowUpdateState(f, FLOW_STATE_CAPTURE_BYPASSED);
/* set accounting, we can't know the direction, so let's just start to
* server then if we already have something in to server to client. We need
* these numbers as we will use it to see if we have new traffic coming
if (fc == NULL) {
fc = SCCalloc(sizeof(FlowBypassInfo), 1);
if (fc) {
+ FlowUpdateState(f, FLOW_STATE_CAPTURE_BYPASSED);
FlowSetStorageById(f, GetFlowBypassInfoID(), fc);
fc->BypassUpdate = EBPFBypassUpdate;
fc->BypassFree = EBPFBypassFree;
fc->todstpktcnt = pkts_cnt;
fc->todstbytecnt = bytes_cnt;
+ f->livedev = dev;
EBPFBypassData *eb = SCCalloc(1, sizeof(EBPFBypassData));
if (eb == NULL) {
SCFree(fc);
FLOWLOCK_UNLOCK(f);
return false;
}
- eb->key[0] = key;
+ void *mkey = SCCalloc(1, skey);
+ if (mkey == NULL) {
+ SCFree(fc);
+ SCFree(eb);
+ FLOWLOCK_UNLOCK(f);
+ return false;
+ }
+ memcpy(mkey, key, skey);
+ eb->key[0] = mkey;
eb->mapfd = mapfd;
eb->cpus_count = cpus_count;
fc->bypass_data = eb;
+ flowstats->count++;
} else {
FLOWLOCK_UNLOCK(f);
return false;
}
} else {
+ EBPFBypassData *eb = (EBPFBypassData *) fc->bypass_data;
+ if (eb == NULL) {
+ FLOWLOCK_UNLOCK(f);
+ return false;
+ }
+ /* if both keys are here, then it is a flow bypassed by this
+ * instance so we ignore it */
+ if (eb->key[0] && eb->key[1]) {
+ FLOWLOCK_UNLOCK(f);
+ return false;
+ }
fc->tosrcpktcnt = pkts_cnt;
fc->tosrcbytecnt = bytes_cnt;
- EBPFBypassData *eb = (EBPFBypassData *) fc->bypass_data;
- if (eb) {
- eb->key[1] = key;
+ void *mkey = SCCalloc(1, skey);
+ if (mkey == NULL) {
+ FLOWLOCK_UNLOCK(f);
+ return false;
}
+ memcpy(mkey, key, skey);
+ eb->key[1] = mkey;
}
f->livedev = dev;
FLOWLOCK_UNLOCK(f);
return false;
}
-typedef bool (*OpFlowForKey)(struct flows_stats *flowstats, LiveDevice*dev, void *key,
- FlowKey *flow_key, struct timespec *ctime,
+typedef bool (*OpFlowForKey)(struct flows_stats * flowstats, LiveDevice*dev, void *key,
+ size_t skey, FlowKey *flow_key, struct timespec *ctime,
uint64_t pkts_cnt, uint64_t bytes_cnt,
int mapfd, int cpus_count);
* looking for timeouted flow to delete from the flow table.
*/
static int EBPFForEachFlowV4Table(ThreadVars *th_v, LiveDevice *dev, const char *name,
- struct flows_stats *flowstats,
struct timespec *ctime,
struct ebpf_timeout_config *tcfg,
OpFlowForKey EBPFOpFlowForKey
)
{
+ struct flows_stats flowstats = { 0, 0, 0};
int mapfd = EBPFGetMapFDByName(dev->dev, name);
if (mapfd == -1)
return -1;
flow_key.proto = IPPROTO_UDP;
}
flow_key.recursion_level = 0;
- dead_flow = EBPFOpFlowForKey(flowstats, dev, &next_key, &flow_key,
+ dead_flow = EBPFOpFlowForKey(&flowstats, dev, &next_key, sizeof(next_key), &flow_key,
ctime, pkts_cnt, bytes_cnt,
mapfd, tcfg->cpus_count);
if (dead_flow) {
EBPFDeleteKey(mapfd, &key);
found = 1;
}
- SC_ATOMIC_ADD(dev->bypassed, flowstats->packets);
+ SC_ATOMIC_ADD(dev->bypassed, flowstats.packets);
- LiveDevSetBypassStats(dev, hash_cnt, AF_INET);
+ LiveDevAddBypassStats(dev, flowstats.count, AF_INET);
SCLogInfo("IPv4 bypassed flow table size: %" PRIu64, hash_cnt);
return found;
*/
static int EBPFForEachFlowV6Table(ThreadVars *th_v,
LiveDevice *dev, const char *name,
- struct flows_stats *flowstats,
struct timespec *ctime,
struct ebpf_timeout_config *tcfg,
OpFlowForKey EBPFOpFlowForKey
)
{
+ struct flows_stats flowstats = { 0, 0, 0};
int mapfd = EBPFGetMapFDByName(dev->dev, name);
if (mapfd == -1)
return -1;
flow_key.proto = IPPROTO_UDP;
}
flow_key.recursion_level = 0;
- pkts_cnt = EBPFOpFlowForKey(flowstats, dev, &next_key, &flow_key,
+ pkts_cnt = EBPFOpFlowForKey(&flowstats, dev, &next_key, sizeof(next_key), &flow_key,
ctime, pkts_cnt, bytes_cnt,
mapfd, tcfg->cpus_count);
if (pkts_cnt > 0) {
EBPFDeleteKey(mapfd, &key);
found = 1;
}
- SC_ATOMIC_ADD(dev->bypassed, flowstats->packets);
+ SC_ATOMIC_ADD(dev->bypassed, flowstats.packets);
- LiveDevSetBypassStats(dev, hash_cnt, AF_INET6);
+ LiveDevAddBypassStats(dev, flowstats.count, AF_INET6);
SCLogInfo("IPv6 bypassed flow table size: %" PRIu64, hash_cnt);
return found;
}
int EBPFCheckBypassedFlowCreate(ThreadVars *th_v, struct timespec *curtime, void *data)
{
- struct flows_stats local_bypassstats = { 0, 0, 0};
LiveDevice *ldev = NULL, *ndev;
struct ebpf_timeout_config *cfg = (struct ebpf_timeout_config *)data;
while(LiveDeviceForEach(&ldev, &ndev)) {
EBPFForEachFlowV4Table(th_v, ldev, "flow_table_v4",
- &local_bypassstats, curtime,
+ curtime,
cfg, EBPFCreateFlowForKey);
EBPFForEachFlowV6Table(th_v, ldev, "flow_table_v6",
- &local_bypassstats, curtime,
+ curtime,
cfg, EBPFCreateFlowForKey);
}