return 1;
}
-static int AFPSetFlowStorage(Packet *p, int map_fd, void *key0, void* key1)
+static int AFPSetFlowStorage(Packet *p, int map_fd, void *key0, void* key1,
+ int family)
{
FlowBypassInfo *fc = FlowGetStorageById(p->flow, GetFlowBypassInfoID());
if (fc) {
EBPFBypassData *eb = SCCalloc(1, sizeof(EBPFBypassData));
if (eb == NULL) {
+ EBPFDeleteKey(map_fd, key0);
+ EBPFDeleteKey(map_fd, key1);
+ LiveDevAddBypassFail(p->livedev, 1, family);
SCFree(key0);
SCFree(key1);
return 0;
fc->BypassUpdate = EBPFBypassUpdate;
fc->BypassFree = EBPFBypassFree;
fc->bypass_data = eb;
+ } else {
+ EBPFDeleteKey(map_fd, key0);
+ EBPFDeleteKey(map_fd, key1);
+ LiveDevAddBypassFail(p->livedev, 1, family);
+ SCFree(key0);
+ SCFree(key1);
+ return 0;
}
+
+ LiveDevAddBypassStats(p->livedev, 1, family);
return 1;
}
}
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[0],
p->afp_v.nr_cpus) == 0) {
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET);
SCFree(keys[0]);
return 0;
}
keys[1]= SCCalloc(1, sizeof(struct flowv4_keys));
if (keys[1] == NULL) {
+ EBPFDeleteKey(p->afp_v.v4_map_fd, keys[0]);
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET);
SCFree(keys[0]);
return 0;
}
keys[1]->ip_proto = keys[0]->ip_proto;
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[1],
p->afp_v.nr_cpus) == 0) {
+ EBPFDeleteKey(p->afp_v.v4_map_fd, keys[0]);
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET);
SCFree(keys[0]);
SCFree(keys[1]);
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]);
+ return AFPSetFlowStorage(p, p->afp_v.v4_map_fd, keys[0], keys[1], AF_INET);
}
/* For IPv6 case we don't handle extended header in eBPF */
if (PKT_IS_IPV6(p) &&
struct flowv6_keys *keys[2];
keys[0] = SCCalloc(1, sizeof(struct flowv6_keys));
if (keys[0] == NULL) {
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
return 0;
}
for (i = 0; i < 4; i++) {
}
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[0],
p->afp_v.nr_cpus) == 0) {
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
SCFree(keys[0]);
return 0;
}
keys[1]= SCCalloc(1, sizeof(struct flowv6_keys));
if (keys[1] == NULL) {
+ EBPFDeleteKey(p->afp_v.v6_map_fd, keys[0]);
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
SCFree(keys[0]);
return 0;
}
keys[1]->ip_proto = keys[0]->ip_proto;
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[1],
p->afp_v.nr_cpus) == 0) {
+ EBPFDeleteKey(p->afp_v.v6_map_fd, keys[0]);
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
SCFree(keys[0]);
SCFree(keys[1]);
return 0;
}
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]);
+ return AFPSetFlowStorage(p, p->afp_v.v6_map_fd, keys[0], keys[1], AF_INET6);
}
#endif
return 0;
struct flowv4_keys *keys[2];
keys[0]= SCCalloc(1, sizeof(struct flowv4_keys));
if (keys[0] == NULL) {
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET);
return 0;
}
if (p->afp_v.v4_map_fd == -1) {
}
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[0],
p->afp_v.nr_cpus) == 0) {
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET);
SCFree(keys[0]);
return 0;
}
keys[1]= SCCalloc(1, sizeof(struct flowv4_keys));
if (keys[1] == NULL) {
+ EBPFDeleteKey(p->afp_v.v4_map_fd, keys[0]);
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET);
SCFree(keys[0]);
return 0;
}
keys[1]->ip_proto = keys[0]->ip_proto;
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[1],
p->afp_v.nr_cpus) == 0) {
+ EBPFDeleteKey(p->afp_v.v4_map_fd, keys[0]);
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET);
SCFree(keys[0]);
SCFree(keys[1]);
return 0;
}
- LiveDevAddBypassStats(p->livedev, 1, AF_INET);
- return AFPSetFlowStorage(p, p->afp_v.v4_map_fd, keys[0], keys[1]);
+ return AFPSetFlowStorage(p, p->afp_v.v4_map_fd, keys[0], keys[1], AF_INET);
}
/* For IPv6 case we don't handle extended header in eBPF */
if (PKT_IS_IPV6(p) &&
}
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[0],
p->afp_v.nr_cpus) == 0) {
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
SCFree(keys[0]);
return 0;
}
keys[1]= SCCalloc(1, sizeof(struct flowv6_keys));
if (keys[1] == NULL) {
+ EBPFDeleteKey(p->afp_v.v6_map_fd, keys[0]);
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
SCFree(keys[0]);
return 0;
}
keys[1]->ip_proto = keys[0]->ip_proto;
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[1],
p->afp_v.nr_cpus) == 0) {
+ EBPFDeleteKey(p->afp_v.v6_map_fd, keys[0]);
+ LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
SCFree(keys[0]);
SCFree(keys[1]);
return 0;
}
- LiveDevAddBypassStats(p->livedev, 1, AF_INET6);
- return AFPSetFlowStorage(p, p->afp_v.v6_map_fd, keys[0], keys[1]);
+ return AFPSetFlowStorage(p, p->afp_v.v6_map_fd, keys[0], keys[1], AF_INET6);
}
#endif
return 0;
typedef struct BypassInfo_ {
SC_ATOMIC_DECLARE(uint64_t, ipv4_hash_count);
+ SC_ATOMIC_DECLARE(uint64_t, ipv4_fail);
+ SC_ATOMIC_DECLARE(uint64_t, ipv4_success);
SC_ATOMIC_DECLARE(uint64_t, ipv6_hash_count);
+ SC_ATOMIC_DECLARE(uint64_t, ipv6_fail);
+ SC_ATOMIC_DECLARE(uint64_t, ipv6_success);
} BypassInfo;
/** if set to 0 when we don't have real devices */
if (bpfdata) {
if (family == AF_INET) {
SC_ATOMIC_ADD(bpfdata->ipv4_hash_count, cnt);
+ SC_ATOMIC_ADD(bpfdata->ipv4_success, cnt);
} else if (family == AF_INET6) {
SC_ATOMIC_ADD(bpfdata->ipv6_hash_count, cnt);
+ SC_ATOMIC_ADD(bpfdata->ipv6_success, cnt);
}
}
}
}
}
+/**
+ * Increase number of failed captured flows for a protocol family
+ *
+ * \param dev pointer to LiveDevice to set stats for
+ * \param cnt number of flows to add
+ * \param family AF_INET to set IPv4 count or AF_INET6 to set IPv6 count
+ */
+void LiveDevAddBypassFail(LiveDevice *dev, uint64_t cnt, int family)
+{
+ BypassInfo *bpfdata = LiveDevGetStorageById(dev, g_bypass_storage_id);
+ if (bpfdata) {
+ if (family == AF_INET) {
+ SC_ATOMIC_ADD(bpfdata->ipv4_fail, cnt);
+ } else if (family == AF_INET6) {
+ SC_ATOMIC_ADD(bpfdata->ipv6_fail, cnt);
+ }
+ }
+}
+
+
+
#ifdef BUILD_UNIX_SOCKET
TmEcode LiveDeviceGetBypassedStats(json_t *cmd, json_t *answer, void *data)
{
if (bpinfo) {
uint64_t ipv4_hash_count = SC_ATOMIC_GET(bpinfo->ipv4_hash_count);
uint64_t ipv6_hash_count = SC_ATOMIC_GET(bpinfo->ipv6_hash_count);
+ uint64_t ipv4_success = SC_ATOMIC_GET(bpinfo->ipv4_success);
+ uint64_t ipv4_fail = SC_ATOMIC_GET(bpinfo->ipv4_fail);
+ uint64_t ipv6_success = SC_ATOMIC_GET(bpinfo->ipv6_success);
+ uint64_t ipv6_fail = SC_ATOMIC_GET(bpinfo->ipv6_fail);
json_t *iface = json_object();
if (ifaces == NULL) {
ifaces = json_object();
return TM_ECODE_FAILED;
}
}
- json_object_set_new(iface, "ipv4_count", json_integer(ipv4_hash_count));
- json_object_set_new(iface, "ipv6_count", json_integer(ipv6_hash_count));
+ json_object_set_new(iface, "ipv4_maps_count", json_integer(ipv4_hash_count));
+ json_object_set_new(iface, "ipv4_success", json_integer(ipv4_success));
+ json_object_set_new(iface, "ipv4_fail", json_integer(ipv4_fail));
+ json_object_set_new(iface, "ipv6_maps_count", json_integer(ipv6_hash_count));
+ json_object_set_new(iface, "ipv6_success", json_integer(ipv6_success));
+ json_object_set_new(iface, "ipv6_fail", json_integer(ipv6_fail));
json_object_set_new(ifaces, ldev->dev, iface);
}
}