suricata
flow-bypass.c
Go to the documentation of this file.
1 /* Copyright (C) 2016-2018 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 /**
19  * \file
20  *
21  * \author Eric Leblond <eleblond@stamus-networks.com>
22  */
23 
24 #include "suricata-common.h"
25 #include "tm-threads.h"
26 #include "flow.h"
27 #include "flow-bypass.h"
28 #include "flow-private.h"
29 #include "util-ebpf.h"
30 
31 #define FLOW_BYPASS_DELAY 10
32 
38 
39 #define BYPASSFUNCMAX 4
42 
45 
46 static TmEcode BypassedFlowManager(ThreadVars *th_v, void *thread_data)
47 {
48 #ifdef HAVE_PACKET_EBPF
49  int tcount = 0;
50  BypassedFlowManagerThreadData *ftd = thread_data;
51  while (1) {
52  int i;
53  SCLogDebug("Dumping the table");
54  struct timespec curtime;
55  if (clock_gettime(CLOCK_MONOTONIC, &curtime) != 0) {
56  SCLogWarning(SC_ERR_INVALID_VALUE, "Can't get time: %s (%d)",
57  strerror(errno), errno);
58  usleep(10000);
59  continue;
60  }
61  for (i = 0; i < g_bypassed_func_max_index; i++) {
62  struct flows_stats bypassstats = { 0, 0, 0};
63  tcount = BypassedFuncList[i](&bypassstats, &curtime);
64  if (tcount) {
65  StatsAddUI64(th_v, ftd->flow_bypassed_cnt_clo, (uint64_t)bypassstats.count);
66  StatsAddUI64(th_v, ftd->flow_bypassed_pkts, (uint64_t)bypassstats.packets);
67  StatsAddUI64(th_v, ftd->flow_bypassed_bytes, (uint64_t)bypassstats.bytes);
68  }
69  }
70 
71  if (TmThreadsCheckFlag(th_v, THV_KILL)) {
72  StatsSyncCounters(th_v);
73  return TM_ECODE_OK;
74  }
75  for (i = 0; i < FLOW_BYPASS_DELAY * 100; i++) {
76  if (TmThreadsCheckFlag(th_v, THV_KILL)) {
77  StatsSyncCounters(th_v);
78  return TM_ECODE_OK;
79  }
81  usleep(10000);
82  }
83  }
84 #endif
85  return TM_ECODE_OK;
86 }
87 
89 {
90  int i;
91 
92  for (i = 0; i < g_bypassed_update_max_index; i++) {
93  if (UpdateFuncList[i](f, p)) {
94  return;
95  }
96  }
97 }
98 
99 static TmEcode BypassedFlowManagerThreadInit(ThreadVars *t, const void *initdata, void **data)
100 {
102  if (ftd == NULL)
103  return TM_ECODE_FAILED;
104 
105  *data = ftd;
106 
107  ftd->flow_bypassed_cnt_clo = StatsRegisterCounter("flow_bypassed.closed", t);
108  ftd->flow_bypassed_pkts = StatsRegisterCounter("flow_bypassed.pkts", t);
109  ftd->flow_bypassed_bytes = StatsRegisterCounter("flow_bypassed.bytes", t);
110 
111  return TM_ECODE_OK;
112 }
113 
114 static TmEcode BypassedFlowManagerThreadDeinit(ThreadVars *t, void *data)
115 {
116  if (data)
117  SCFree(data);
118  return TM_ECODE_OK;
119 }
120 
121 /** \brief spawn the flow manager thread */
123 {
124 #ifdef AFLFUZZ_DISABLE_MGTTHREADS
125  return;
126 #endif
127 
128  ThreadVars *tv_flowmgr = NULL;
130  "BypassedFlowManager", 0);
131  BUG_ON(tv_flowmgr == NULL);
132 
133  if (tv_flowmgr == NULL) {
134  printf("ERROR: TmThreadsCreate failed\n");
135  exit(1);
136  }
137  if (TmThreadSpawn(tv_flowmgr) != TM_ECODE_OK) {
138  printf("ERROR: TmThreadSpawn failed\n");
139  exit(1);
140  }
141 }
142 
144 {
145  if (!CheckFunc) {
146  return -1;
147  }
151  } else {
152  return -1;
153  }
154  return 0;
155 }
156 
158 {
159  if (!UpdateFunc) {
160  return -1;
161  }
165  } else {
166  return -1;
167  }
168  return 0;
169 }
170 
172 {
173  tmm_modules[TMM_BYPASSEDFLOWMANAGER].name = "BypassedFlowManager";
174  tmm_modules[TMM_BYPASSEDFLOWMANAGER].ThreadInit = BypassedFlowManagerThreadInit;
175  tmm_modules[TMM_BYPASSEDFLOWMANAGER].ThreadDeinit = BypassedFlowManagerThreadDeinit;
176  tmm_modules[TMM_BYPASSEDFLOWMANAGER].Management = BypassedFlowManager;
179  SCLogDebug("%s registered", tmm_modules[TMM_BYPASSEDFLOWMANAGER].name);
180 }
181 
#define SCLogDebug(...)
Definition: util-debug.h:335
uint8_t cap_flags
Definition: tm-modules.h:67
#define BUG_ON(x)
uint8_t flags
Definition: tm-modules.h:70
int g_bypassed_func_max_index
Definition: flow-bypass.c:40
struct BypassedFlowManagerThreadData_ BypassedFlowManagerThreadData
const char * thread_name_flow_bypass
Definition: runmodes.c:67
int(* BypassedCheckFunc)(struct flows_stats *bypassstats, struct timespec *curtime)
Definition: flow-bypass.h:33
int BypassedFlowManagerRegisterCheckFunc(BypassedCheckFunc CheckFunc)
Definition: flow-bypass.c:143
int BypassedFlowManagerRegisterUpdateFunc(BypassedUpdateFunc UpdateFunc)
Definition: flow-bypass.c:157
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:939
#define SCCalloc(nm, a)
Definition: util-mem.h:197
TmEcode(* Management)(ThreadVars *, void *)
Definition: tm-modules.h:59
#define TM_FLAG_MANAGEMENT_TM
Definition: tm-modules.h:36
#define BYPASSFUNCMAX
Definition: flow-bypass.c:39
#define FLOW_BYPASS_DELAY
Definition: flow-bypass.c:31
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
ThreadVars * TmThreadCreateMgmtThreadByName(const char *name, const char *module, int mucond)
Creates and returns the TV instance for a Management thread(MGMT). This function supports only custom...
Definition: tm-threads.c:1295
#define THV_KILL
Definition: threadvars.h:39
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
void BypassedFlowManagerThreadSpawn()
spawn the flow manager thread
Definition: flow-bypass.c:122
const char * name
Definition: tm-modules.h:44
#define SCFree(a)
Definition: util-mem.h:228
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.h:73
int(* BypassedUpdateFunc)(Flow *f, Packet *p)
Definition: flow-bypass.h:35
int g_bypassed_update_max_index
Definition: flow-bypass.c:43
#define StatsSyncCountersIfSignalled(tv)
Definition: counters.h:136
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
int TmThreadsCheckFlag(ThreadVars *tv, uint16_t flag)
Check if a thread flag is set.
Definition: tm-threads.c:90
BypassedUpdateFunc UpdateFuncList[BYPASSFUNCMAX]
Definition: flow-bypass.c:44
#define StatsSyncCounters(tv)
Definition: counters.h:133
void TmModuleBypassedFlowManagerRegister(void)
Definition: flow-bypass.c:171
Per thread variable structure.
Definition: threadvars.h:57
void StatsAddUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Adds a value of type uint64_t to the local counter.
Definition: counters.c:142
BypassedCheckFunc BypassedFuncList[BYPASSFUNCMAX]
Definition: flow-bypass.c:41
void BypassedFlowUpdate(Flow *f, Packet *p)
Definition: flow-bypass.c:88
TmEcode TmThreadSpawn(ThreadVars *tv)
Spawns a thread associated with the ThreadVars instance tv.
Definition: tm-threads.c:1867
Flow data structure.
Definition: flow.h:325