diff --git a/src/flow-manager.c b/src/flow-manager.c index e2c32b3c9b..6f3603e6ca 100644 --- a/src/flow-manager.c +++ b/src/flow-manager.c @@ -285,6 +285,13 @@ static int FlowManagerFlowTimeout(Flow *f, enum FlowState state, struct timeval return 0; } else { SCLogDebug("No new packet, dead flow %ld", FlowGetId(f)); + if (f->livedev) { + if (FLOW_IS_IPV4(f)) { + LiveDevAddBypassStats(f->livedev, -1, AF_INET); + } else if (FLOW_IS_IPV6(f)) { + LiveDevAddBypassStats(f->livedev, -1, AF_INET6); + } + } if (counters) { counters->bypassed_count++; } diff --git a/src/source-af-packet.c b/src/source-af-packet.c index 98ad3337ea..68ad9acfd3 100644 --- a/src/source-af-packet.c +++ b/src/source-af-packet.c @@ -2436,6 +2436,7 @@ static int AFPBypassCallback(Packet *p) return 0; } EBPFUpdateFlow(p->flow, p, NULL); + LiveDevAddBypassStats(p->livedev, 1, AF_INET); return AFPSetFlowStorage(p, p->afp_v.v4_map_fd, keys[0], keys[1]); } /* For IPv6 case we don't handle extended header in eBPF */ @@ -2493,6 +2494,7 @@ static int AFPBypassCallback(Packet *p) } if (p->flow) EBPFUpdateFlow(p->flow, p, NULL); + LiveDevAddBypassStats(p->livedev, 1, AF_INET6); return AFPSetFlowStorage(p, p->afp_v.v6_map_fd, keys[0], keys[1]); } #endif @@ -2577,6 +2579,7 @@ static int AFPXDPBypassCallback(Packet *p) SCFree(keys[1]); return 0; } + LiveDevAddBypassStats(p->livedev, 1, AF_INET); return AFPSetFlowStorage(p, p->afp_v.v4_map_fd, keys[0], keys[1]); } /* For IPv6 case we don't handle extended header in eBPF */ @@ -2631,6 +2634,7 @@ static int AFPXDPBypassCallback(Packet *p) SCFree(keys[1]); return 0; } + LiveDevAddBypassStats(p->livedev, 1, AF_INET6); return AFPSetFlowStorage(p, p->afp_v.v6_map_fd, keys[0], keys[1]); } #endif diff --git a/src/util-device.c b/src/util-device.c index 2eecc11f9c..64506ef989 100644 --- a/src/util-device.c +++ b/src/util-device.c @@ -513,6 +513,26 @@ void LiveDevSetBypassStats(LiveDevice *dev, uint64_t cnt, int family) } } +/** + * Modify number of currently bypassed flows for a protocol family + * + * \param dev pointer to LiveDevice to set stats for + * \param cnt number of currently bypassed flows + * \param family AF_INET to set IPv4 count or AF_INET6 to set IPv6 count + */ +void LiveDevAddBypassStats(LiveDevice *dev, int64_t cnt, int family) +{ + BypassInfo *bpfdata = LiveDevGetStorageById(dev, g_bypass_storage_id); + if (bpfdata) { + if (family == AF_INET) { + SC_ATOMIC_ADD(bpfdata->ipv4_hash_count, cnt); + } else if (family == AF_INET6) { + SC_ATOMIC_ADD(bpfdata->ipv6_hash_count, cnt); + } + } +} + + #ifdef BUILD_UNIX_SOCKET TmEcode LiveDeviceGetBypassedStats(json_t *cmd, json_t *answer, void *data) { diff --git a/src/util-device.h b/src/util-device.h index a8991af97c..e2eebf4770 100644 --- a/src/util-device.h +++ b/src/util-device.h @@ -66,6 +66,7 @@ int LiveRegisterDeviceName(const char *dev); int LiveRegisterDevice(const char *dev); int LiveDevUseBypass(LiveDevice *dev); void LiveDevSetBypassStats(LiveDevice *dev, uint64_t cnt, int family); +void LiveDevAddBypassStats(LiveDevice *dev, int64_t cnt, int family); int LiveGetDeviceCount(void); const char *LiveGetDeviceName(int number); LiveDevice *LiveGetDevice(const char *dev);