From dc85e3941c26b80d575d30aaeff821e6f4ec4a00 Mon Sep 17 00:00:00 2001
From: Peter Haag <peter@people.ops-trust.net>
Date: Sat, 31 Aug 2024 20:35:25 +0200
Subject: [PATCH] Addint64 and uint64 config routines

---
 src/libnffile/conf/nfconf.c         | 62 +++++++++++++++++++++++++++++
 src/libnffile/conf/nfconf.h         |  8 ++++
 src/libnffile/conf/nfdump.conf.dist |  1 +
 src/sflow/sfcapd.c                  | 19 ++++++---
 4 files changed, 84 insertions(+), 6 deletions(-)

diff --git a/src/libnffile/conf/nfconf.c b/src/libnffile/conf/nfconf.c
index 08be8a12..fc8fb15f 100644
--- a/src/libnffile/conf/nfconf.c
+++ b/src/libnffile/conf/nfconf.c
@@ -429,6 +429,68 @@ int SetNameserver(char *ns) {
 
 }  // End of set_nameserver
 
+int ConfGetInt64(option_t *optionList, char *key, uint64_t *valInt64) {
+    int i = 0;
+    while (optionList[i].name != NULL) {
+        if (strcmp(optionList[i].name, key) == 0) {
+            if (optionList[i].flags == OPTDEFAULT) {
+                int confInt64 = ConfGetValue(key);
+                *valInt64 = confInt64;
+                return 1;
+            } else {
+                *valInt64 = optionList[i].valInt64;
+                return 1;
+            }
+        }
+        i++;
+    }
+    return 0;
+}  // End of ConfGetInt64
+
+int ConfSetInt64(option_t *optionList, char *key, uint64_t valInt64) {
+    int i = 0;
+    while (optionList[i].name != NULL) {
+        if (strcmp(optionList[i].name, key) == 0) {
+            optionList[i].valInt64 = valInt64;
+            optionList[i].flags = OPTSET;
+            return 1;
+        }
+        i++;
+    }
+    return 0;
+}  // End of ConfSetInt64
+
+int ConfGetUint64(option_t *optionList, char *key, uint64_t *valUint64) {
+    int i = 0;
+    while (optionList[i].name != NULL) {
+        if (strcmp(optionList[i].name, key) == 0) {
+            if (optionList[i].flags == OPTDEFAULT) {
+                int confUint64 = ConfGetValue(key);
+                *valUint64 = confUint64;
+                return 1;
+            } else {
+                *valUint64 = optionList[i].valUint64;
+                return 1;
+            }
+        }
+        i++;
+    }
+    return 0;
+}  // ConfGetUint64
+
+int ConfSetUint64(option_t *optionList, char *key, uint64_t valUint64) {
+    int i = 0;
+    while (optionList[i].name != NULL) {
+        if (strcmp(optionList[i].name, key) == 0) {
+            optionList[i].valUint64 = valUint64;
+            optionList[i].flags = OPTSET;
+            return 1;
+        }
+        i++;
+    }
+    return 0;  // End of
+}  // End of ConfSetUint64
+
 int scanOptions(option_t *optionList, char *options) {
     if (options == NULL) return 1;
 
diff --git a/src/libnffile/conf/nfconf.h b/src/libnffile/conf/nfconf.h
index 2e2de3fd..0497b31f 100644
--- a/src/libnffile/conf/nfconf.h
+++ b/src/libnffile/conf/nfconf.h
@@ -58,6 +58,14 @@ char *ConfGetString(char *key);
 
 int ConfGetValue(char *key);
 
+int ConfGetInt64(option_t *optionList, char *key, uint64_t *valOnt64);
+
+int ConfSetInt64(option_t *optionList, char *key, uint64_t valInt64);
+
+int ConfGetUint64(option_t *optionList, char *key, uint64_t *valUint64);
+
+int ConfSetUint64(option_t *optionList, char *key, uint64_t valUint64);
+
 int SetNameserver(char *ns);
 
 int scanOptions(option_t *optionList, char *options);
diff --git a/src/libnffile/conf/nfdump.conf.dist b/src/libnffile/conf/nfdump.conf.dist
index f4277000..9ef24ef8 100644
--- a/src/libnffile/conf/nfdump.conf.dist
+++ b/src/libnffile/conf/nfdump.conf.dist
@@ -65,6 +65,7 @@ fmt.pflog = "%ts %pfact %pfrea  %pfdir on %pfifn %pfrule  %pr %sap -> %dap %pkt
 [sfcapd]
 # define -o options
 # opt.gre = 1
+# maxworkers = 16
 
 [nfpcapd]
 # define -o options
diff --git a/src/sflow/sfcapd.c b/src/sflow/sfcapd.c
index 8f9bc0af..16c4004d 100644
--- a/src/sflow/sfcapd.c
+++ b/src/sflow/sfcapd.c
@@ -95,7 +95,8 @@ static int verbose = 0;
 // Define a generic type to get data from socket or pcap file
 typedef ssize_t (*packet_function_t)(int, void *, size_t, int, struct sockaddr *, socklen_t *);
 
-static option_t sfcapdOption[] = {{.name = "gre", .valBool = 0, .flags = OPTDEFAULT}, {.name = NULL}};
+static option_t sfcapdConfig[] = {
+    {.name = "gre", .valBool = 0, .flags = OPTDEFAULT}, {.name = "maxworkers", .valUint64 = 2, .flags = OPTDEFAULT}, {.name = NULL}};
 
 /* module limited globals */
 static FlowSource_t *FlowSource;
@@ -458,7 +459,8 @@ int main(int argc, char **argv) {
     int family, bufflen, metricInterval;
     time_t twin;
     int sock, do_daemonize, expire, spec_time_extension, parse_gre;
-    int subdir_index, compress, srcSpoofing, workers;
+    int subdir_index, compress, srcSpoofing;
+    uint64_t workers;
 #ifdef PCAP
     char *pcap_file = NULL;
     char *pcap_device = NULL;
@@ -684,11 +686,15 @@ int main(int argc, char **argv) {
                 break;
             case 'W':
                 CheckArgLen(optarg, 16);
-                workers = atoi(optarg);
-                if (workers < 0 || workers > MAXWORKERS) {
+                workers = (uint64_t)atoi(optarg);
+                if (workers < 1 || workers > MAXWORKERS) {
                     LogError("Number of working threads out of range 1..%d", MAXWORKERS);
                     exit(EXIT_FAILURE);
                 }
+                if (!ConfSetUint64(sfcapdConfig, "maxworkers", workers)) {
+                    LogError("Failed to set conf value");
+                    exit(EXIT_FAILURE);
+                }
                 break;
             case 'j':
                 if (compress) {
@@ -776,10 +782,10 @@ int main(int argc, char **argv) {
 
     if (ConfOpen(configFile, "sfcapd") < 0) exit(EXIT_FAILURE);
 
-    if (scanOptions(sfcapdOption, options) == 0) {
+    if (scanOptions(sfcapdConfig, options) == 0) {
         exit(EXIT_FAILURE);
     }
-    OptGetBool(sfcapdOption, "gre", &parse_gre);
+    OptGetBool(sfcapdConfig, "gre", &parse_gre);
 
     if (datadir && !AddFlowSource(&FlowSource, Ident, ANYIP, datadir)) {
         LogError("Failed to add default data collector directory");
@@ -801,6 +807,7 @@ int main(int argc, char **argv) {
         exit(EXIT_FAILURE);
     }
 
+    ConfGetUint64(sfcapdConfig, "maxworkers", &workers);
     if (!Init_nffile(workers, NULL)) exit(254);
 
     if (expire && spec_time_extension) {