From: Eric Leblond Date: Sun, 7 Jan 2018 20:47:43 +0000 (+0100) Subject: util-ebpf: simplify code cleaning X-Git-Tag: suricata-4.1.0-beta1~190 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b56b02569d8d79da3de98d5f11884afa502aec0;p=thirdparty%2Fsuricata.git util-ebpf: simplify code cleaning Avoid to use an unnecessary callback strategy as the purpose of the function using the callback is hardcoded. --- diff --git a/src/util-ebpf.c b/src/util-ebpf.c index 8b18c3697e..b46d8a7ac5 100644 --- a/src/util-ebpf.c +++ b/src/util-ebpf.c @@ -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 ;