util-ebpf: simplify code cleaning

Avoid to use an unnecessary callback strategy as the purpose of the
function using the callback is hardcoded.
pull/3221/head
Eric Leblond 8 years ago
parent 94a622cb55
commit 2b56b02569

@ -290,6 +290,74 @@ int EBPFSetupXDP(const char *iface, int fd, uint8_t flags)
return 0;
}
/**
* Decide if an IPV4 flow needs to be timeouted
*
* The filter is maintaining for each half flow a struct pair:: structure in
* the kernel where it does accounting and timestamp update. So by comparing
* the current timestamp to the timestamp in the struct pair we can know that
* no packet have been seen on a half flow since a certain delay.
*
* If a per-CPU array map is used, this function has only a per-CPU view so
* the flow will be deleted from the table if EBPFBypassedFlowV4Timeout() return
* 1 for all CPUs.
*
* \param fd the file descriptor of the flow table map
* \param key the key of the element
* \param value the value of the element in the hash
* \param curtime the current time
* \return 1 if timeouted 0 if not
*/
static int EBPFBypassedFlowV4Timeout(int fd, struct flowv4_keys *key,
struct pair *value, struct timespec *curtime)
{
SCLogDebug("Got curtime %" PRIu64 " and value %" PRIu64 " (sp:%d, dp:%d) %u",
curtime->tv_sec, value->time / 1000000000,
key->port16[0], key->port16[1], key->ip_proto
);
if (curtime->tv_sec - value->time / 1000000000 > BYPASSED_FLOW_TIMEOUT) {
SCLogDebug("Got no packet for %d -> %d at %" PRIu64,
key->port16[0], key->port16[1], value->time);
return 1;
}
return 0;
}
/**
* Decide if an IPV6 flow needs to be timeouted
*
* The filter is maintaining for each half flow a struct pair:: structure in
* the kernel where it does accounting and timestamp update. So by comparing
* the current timestamp to the timestamp in the struct pair we can know that
* no packet have been seen on a half flow since a certain delay.
*
* If a per-CPU array map is used, this function has only a per-CPU view so
* the flow will be deleted from the table if EBPFBypassedFlowV4Timeout() return
* 1 for all CPUs.
*
* \param fd the file descriptor of the flow table map
* \param key the key of the element
* \param value the value of the element in the hash
* \param curtime the current time
* \return 1 if timeouted 0 if not
*/
static int EBPFBypassedFlowV6Timeout(int fd, struct flowv6_keys *key,
struct pair *value, struct timespec *curtime)
{
SCLogDebug("Got curtime %" PRIu64 " and value %" PRIu64 " (sp:%d, dp:%d)",
curtime->tv_sec, value->time / 1000000000,
key->port16[0], key->port16[1]
);
if (curtime->tv_sec - value->time / 1000000000 > BYPASSED_FLOW_TIMEOUT) {
SCLogDebug("Got no packet for %d -> %d at %" PRIu64,
key->port16[0], key->port16[1], value->time);
return 1;
}
return 0;
}
/**
* Bypassed flows cleaning for IPv4
*
@ -297,9 +365,8 @@ int EBPFSetupXDP(const char *iface, int fd, uint8_t flags)
* looking for timeouted flow to delete from the flow table.
*/
static int EBPFForEachFlowV4Table(const char *iface, const char *name,
int (*FlowCallback)(int fd, struct flowv4_keys *key, struct pair *value, void *data),
struct flows_stats *flowstats,
void *data)
struct flows_stats *flowstats,
struct timespec *ctime)
{
int mapfd = EBPFGetMapFDByName(iface, name);
struct flowv4_keys key = {}, next_key;
@ -325,7 +392,7 @@ static int EBPFForEachFlowV4Table(const char *iface, const char *name,
continue;
}
for (i = 0; i < nr_cpus; i++) {
int ret = FlowCallback(mapfd, &key, &values_array[i], data);
int ret = EBPFBypassedFlowV4Timeout(mapfd, &key, &values_array[i], ctime);
if (ret) {
/* no packet for the flow on this CPU, let's start accumulating
value so we can compute the counters */
@ -362,9 +429,8 @@ static int EBPFForEachFlowV4Table(const char *iface, const char *name,
* looking for timeouted flow to delete from the flow table.
*/
static int EBPFForEachFlowV6Table(const char *iface, const char *name,
int (*FlowCallback)(int fd, struct flowv6_keys *key, struct pair *value, void *data),
struct flows_stats *flowstats,
void *data)
struct flows_stats *flowstats,
struct timespec *ctime)
{
int mapfd = EBPFGetMapFDByName(iface, name);
struct flowv6_keys key = {}, next_key;
@ -389,7 +455,7 @@ static int EBPFForEachFlowV6Table(const char *iface, const char *name,
continue;
}
for (i = 0; i < nr_cpus; i++) {
int ret = FlowCallback(mapfd, &key, &values_array[i], data);
int ret = EBPFBypassedFlowV6Timeout(mapfd, &key, &values_array[i], ctime);
if (ret) {
pkts_cnt += values_array[i].packets;
bytes_cnt += values_array[i].bytes;
@ -411,74 +477,6 @@ static int EBPFForEachFlowV6Table(const char *iface, const char *name,
return found;
}
/**
* Decide if an IPV4 flow needs to be timeouted
*
* The filter is maintaining for each half flow a struct pair:: structure in
* the kernel where it does accounting and timestamp update. So by comparing
* the current timestamp to the timestamp in the struct pair we can know that
* no packet have been seen on a half flow since a certain delay.
*
* If a per-CPU array map is used, this function has only a per-CPU view so
* the flow will be deleted from the table if EBPFBypassedFlowV4Timeout() return
* 1 for all CPUs.
*
* \param fd the file descriptor of the flow table map
* \param key the key of the element
* \param value the value of the element in the hash
* \param data the current time
* \return 1 if timeouted 0 if not
*/
static int EBPFBypassedFlowV4Timeout(int fd, struct flowv4_keys *key, struct pair *value, void *data)
{
struct timespec *curtime = (struct timespec *)data;
SCLogDebug("Got curtime %" PRIu64 " and value %" PRIu64 " (sp:%d, dp:%d) %u",
curtime->tv_sec, value->time / 1000000000,
key->port16[0], key->port16[1], key->ip_proto
);
if (curtime->tv_sec - value->time / 1000000000 > BYPASSED_FLOW_TIMEOUT) {
SCLogDebug("Got no packet for %d -> %d at %" PRIu64,
key->port16[0], key->port16[1], value->time);
return 1;
}
return 0;
}
/**
* Decide if an IPV6 flow needs to be timeouted
*
* The filter is maintaining for each half flow a struct pair:: structure in
* the kernel where it does accounting and timestamp update. So by comparing
* the current timestamp to the timestamp in the struct pair we can know that
* no packet have been seen on a half flow since a certain delay.
*
* If a per-CPU array map is used, this function has only a per-CPU view so
* the flow will be deleted from the table if EBPFBypassedFlowV4Timeout() return
* 1 for all CPUs.
*
* \param fd the file descriptor of the flow table map
* \param key the key of the element
* \param value the value of the element in the hash
* \param data the current time*
* \return 1 if timeouted 0 if not
*/
static int EBPFBypassedFlowV6Timeout(int fd, struct flowv6_keys *key, struct pair *value, void *data)
{
struct timespec *curtime = (struct timespec *)data;
SCLogDebug("Got curtime %" PRIu64 " and value %" PRIu64 " (sp:%d, dp:%d)",
curtime->tv_sec, value->time / 1000000000,
key->port16[0], key->port16[1]
);
if (curtime->tv_sec - value->time / 1000000000 > BYPASSED_FLOW_TIMEOUT) {
SCLogDebug("Got no packet for %d -> %d at %" PRIu64,
key->port16[0], key->port16[1], value->time);
return 1;
}
return 0;
}
/**
* Flow timeout checking function
*
@ -495,8 +493,8 @@ int EBPFCheckBypassedFlowTimeout(struct flows_stats *bypassstats,
LiveDevice *ldev = NULL, *ndev;
while(LiveDeviceForEach(&ldev, &ndev)) {
tcount = EBPFForEachFlowV4Table(ldev->dev, "flow_table_v4", EBPFBypassedFlowV4Timeout,
&l_bypassstats, curtime);
tcount = EBPFForEachFlowV4Table(ldev->dev, "flow_table_v4",
&l_bypassstats, curtime);
if (tcount) {
bypassstats->count = l_bypassstats.count;
bypassstats->packets = l_bypassstats.packets ;
@ -504,8 +502,8 @@ int EBPFCheckBypassedFlowTimeout(struct flows_stats *bypassstats,
ret = 1;
}
memset(&l_bypassstats, 0, sizeof(l_bypassstats));
tcount = EBPFForEachFlowV6Table(ldev->dev, "flow_table_v6", EBPFBypassedFlowV6Timeout,
&l_bypassstats, curtime);
tcount = EBPFForEachFlowV6Table(ldev->dev, "flow_table_v6",
&l_bypassstats, curtime);
if (tcount) {
bypassstats->count += l_bypassstats.count;
bypassstats->packets += l_bypassstats.packets ;

Loading…
Cancel
Save