Coverage Report

Created: 2026-08-14 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/runmode-erf-file.c
Line
Count
Source
1
/* Copyright (C) 2007-2010 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17
18
#include "suricata-common.h"
19
#include "tm-threads.h"
20
#include "conf.h"
21
#include "runmodes.h"
22
#include "runmode-erf-file.h"
23
#include "output.h"
24
25
#include "detect-engine.h"
26
27
#include "util-debug.h"
28
#include "util-time.h"
29
#include "util-cpu.h"
30
#include "util-affinity.h"
31
32
#include "util-runmodes.h"
33
34
const char *RunModeErfFileGetDefaultMode(void)
35
0
{
36
0
    return "autofp";
37
0
}
38
39
void RunModeErfFileRegister(void)
40
37
{
41
37
    RunModeRegisterNewRunMode(RUNMODE_ERF_FILE, "single", "Single threaded ERF file mode",
42
37
            RunModeErfFileSingle, NULL);
43
44
37
    RunModeRegisterNewRunMode(RUNMODE_ERF_FILE, "autofp",
45
37
            "Multi threaded ERF file mode.  Packets from "
46
37
            "each flow are assigned to a single detect thread",
47
37
            RunModeErfFileAutoFp, NULL);
48
49
37
    return;
50
37
}
51
52
int RunModeErfFileSingle(void)
53
0
{
54
0
    const char *file;
55
56
0
    SCEnter();
57
58
0
    if (ConfGet("erf-file.file", &file) == 0) {
59
0
        FatalError("Failed to get erf-file.file from config.");
60
0
    }
61
62
0
    TimeModeSetOffline();
63
64
    /* Basically the same setup as PCAP files. */
65
66
0
    ThreadVars *tv = TmThreadCreatePacketHandler(thread_name_single,
67
0
        "packetpool", "packetpool",
68
0
        "packetpool", "packetpool",
69
0
        "pktacqloop");
70
0
    if (tv == NULL) {
71
0
        printf("ERROR: TmThreadsCreate failed\n");
72
0
        exit(EXIT_FAILURE);
73
0
    }
74
75
0
    TmModule *tm_module = TmModuleGetByName("ReceiveErfFile");
76
0
    if (tm_module == NULL) {
77
0
        printf("ERROR: TmModuleGetByName failed for ReceiveErfFile\n");
78
0
        exit(EXIT_FAILURE);
79
0
    }
80
0
    TmSlotSetFuncAppend(tv, tm_module, file);
81
82
0
    tm_module = TmModuleGetByName("DecodeErfFile");
83
0
    if (tm_module == NULL) {
84
0
        printf("ERROR: TmModuleGetByName DecodeErfFile failed\n");
85
0
        exit(EXIT_FAILURE);
86
0
    }
87
0
    TmSlotSetFuncAppend(tv, tm_module, NULL);
88
89
0
    tm_module = TmModuleGetByName("FlowWorker");
90
0
    if (tm_module == NULL) {
91
0
        FatalError("TmModuleGetByName for FlowWorker failed");
92
0
    }
93
0
    TmSlotSetFuncAppend(tv, tm_module, NULL);
94
95
0
    if (TmThreadSpawn(tv) != TM_ECODE_OK) {
96
0
        printf("ERROR: TmThreadSpawn failed\n");
97
0
        exit(EXIT_FAILURE);
98
0
    }
99
100
0
    SCLogInfo("RunModeErfFileSingle initialised");
101
102
0
    SCReturnInt(0);
103
0
}
104
105
int RunModeErfFileAutoFp(void)
106
0
{
107
0
    SCEnter();
108
0
    char tname[TM_THREAD_NAME_MAX];
109
0
    char qname[TM_QUEUE_NAME_MAX];
110
0
    uint16_t cpu = 0;
111
0
    char *queues = NULL;
112
0
    uint16_t thread;
113
114
0
    const char *file = NULL;
115
0
    if (ConfGet("erf-file.file", &file) == 0) {
116
0
        FatalError("Failed retrieving erf-file.file from config");
117
0
    }
118
119
0
    TimeModeSetOffline();
120
121
    /* Available cpus */
122
0
    uint16_t ncpus = UtilCpuGetNumProcessorsOnline();
123
124
    /* start with cpu 1 so that if we're creating an odd number of detect
125
     * threads we're not creating the most on CPU0. */
126
0
    if (ncpus > 0)
127
0
        cpu = 1;
128
129
    /* always create at least one thread */
130
0
    int thread_max = TmThreadGetNbThreads(WORKER_CPU_SET);
131
0
    if (thread_max == 0)
132
0
        thread_max = ncpus * threading_detect_ratio;
133
0
    if (thread_max < 1)
134
0
        thread_max = 1;
135
0
    if (thread_max > 1024)
136
0
        thread_max = 1024;
137
138
0
    queues = RunmodeAutoFpCreatePickupQueuesString(thread_max);
139
0
    if (queues == NULL) {
140
0
        FatalError("RunmodeAutoFpCreatePickupQueuesString failed");
141
0
    }
142
143
    /* create the threads */
144
0
    ThreadVars *tv =
145
0
        TmThreadCreatePacketHandler(thread_name_autofp,
146
0
                                    "packetpool", "packetpool",
147
0
                                    queues, "flow",
148
0
                                    "pktacqloop");
149
0
    SCFree(queues);
150
151
0
    if (tv == NULL) {
152
0
        printf("ERROR: TmThreadsCreate failed\n");
153
0
        exit(EXIT_FAILURE);
154
0
    }
155
0
    TmModule *tm_module = TmModuleGetByName("ReceiveErfFile");
156
0
    if (tm_module == NULL) {
157
0
        printf("ERROR: TmModuleGetByName failed for ReceiveErfFile\n");
158
0
        exit(EXIT_FAILURE);
159
0
    }
160
0
    TmSlotSetFuncAppend(tv, tm_module, file);
161
162
0
    tm_module = TmModuleGetByName("DecodeErfFile");
163
0
    if (tm_module == NULL) {
164
0
        printf("ERROR: TmModuleGetByName DecodeErfFile failed\n");
165
0
        exit(EXIT_FAILURE);
166
0
    }
167
0
    TmSlotSetFuncAppend(tv, tm_module, NULL);
168
169
0
    if (threading_set_cpu_affinity) {
170
0
        TmThreadSetCPUAffinity(tv, 0);
171
0
        if (ncpus > 1)
172
0
            TmThreadSetThreadPriority(tv, PRIO_MEDIUM);
173
0
    }
174
175
0
    if (TmThreadSpawn(tv) != TM_ECODE_OK) {
176
0
        printf("ERROR: TmThreadSpawn failed\n");
177
0
        exit(EXIT_FAILURE);
178
0
    }
179
180
0
    for (thread = 0; thread < (uint16_t)thread_max; thread++) {
181
0
        snprintf(tname, sizeof(tname), "%s#%02d", thread_name_workers, thread + 1);
182
0
        snprintf(qname, sizeof(qname), "pickup%d", thread + 1);
183
184
0
        SCLogDebug("tname %s, qname %s", tname, qname);
185
186
0
        SCLogDebug("Assigning %s affinity to cpu %u", tname, cpu);
187
188
0
        ThreadVars *tv_detect_ncpu =
189
0
            TmThreadCreatePacketHandler(tname,
190
0
                                        qname, "flow",
191
0
                                        "packetpool", "packetpool",
192
0
                                        "varslot");
193
0
        if (tv_detect_ncpu == NULL) {
194
0
            printf("ERROR: TmThreadsCreate failed\n");
195
0
            exit(EXIT_FAILURE);
196
0
        }
197
198
0
        tm_module = TmModuleGetByName("FlowWorker");
199
0
        if (tm_module == NULL) {
200
0
            FatalError("TmModuleGetByName for FlowWorker failed");
201
0
        }
202
0
        TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL);
203
204
0
        if (threading_set_cpu_affinity) {
205
0
            TmThreadSetCPUAffinity(tv_detect_ncpu, cpu);
206
            /* If we have more than one core/cpu, the first Detect thread
207
             * (at cpu 0) will have less priority (higher 'nice' value)
208
             * In this case we will set the thread priority to +10 (default is 0)
209
             */
210
0
            if (cpu == 0 && ncpus > 1) {
211
0
                TmThreadSetThreadPriority(tv_detect_ncpu, PRIO_LOW);
212
0
            } else if (ncpus > 1) {
213
0
                TmThreadSetThreadPriority(tv_detect_ncpu, PRIO_MEDIUM);
214
0
            }
215
0
        }
216
217
0
        TmThreadSetGroupName(tv_detect_ncpu, "Detect");
218
219
0
        if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) {
220
0
            printf("ERROR: TmThreadSpawn failed\n");
221
0
            exit(EXIT_FAILURE);
222
0
        }
223
224
0
        if ((cpu + 1) == ncpus)
225
0
            cpu = 0;
226
0
        else
227
0
            cpu++;
228
0
    }
229
230
0
    SCLogInfo("RunModeErfFileAutoFp initialised");
231
232
0
    SCReturnInt(0);
233
0
}