suricata
tmqh-packetpool.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2022 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 Victor Julien <victor@inliniac.net>
22  *
23  * Packetpool queue handlers. Packet pool is implemented as a stack.
24  */
25 
26 #include "suricata-common.h"
27 #include "tmqh-packetpool.h"
28 #include "tm-queuehandlers.h"
29 #include "tm-threads.h"
30 #include "threads.h"
31 #include "decode.h"
32 #include "tm-modules.h"
33 #include "packet.h"
34 #include "util-profiling.h"
35 #include "util-validate.h"
36 #include "action-globals.h"
37 
38 /* Number of freed packet to save for one pool before freeing them. */
39 #define MAX_PENDING_RETURN_PACKETS 32
40 static uint32_t max_pending_return_packets = MAX_PENDING_RETURN_PACKETS;
41 
42 thread_local PktPool thread_pkt_pool;
43 
44 static inline PktPool *GetThreadPacketPool(void)
45 {
46  return &thread_pkt_pool;
47 }
48 
49 /**
50  * \brief TmqhPacketpoolRegister
51  * \initonly
52  */
54 {
55  tmqh_table[TMQH_PACKETPOOL].name = "packetpool";
58 }
59 
60 static int PacketPoolIsEmpty(PktPool *pool)
61 {
62  /* Check local stack first. */
63  if (pool->head || pool->return_stack.head)
64  return 0;
65 
66  return 1;
67 }
68 
69 void PacketPoolWait(void)
70 {
71  PktPool *my_pool = GetThreadPacketPool();
72 
73  if (PacketPoolIsEmpty(my_pool)) {
74  SCMutexLock(&my_pool->return_stack.mutex);
75  SC_ATOMIC_ADD(my_pool->return_stack.sync_now, 1);
76  SCCondWait(&my_pool->return_stack.cond, &my_pool->return_stack.mutex);
77  SCMutexUnlock(&my_pool->return_stack.mutex);
78  }
79 
80  while(PacketPoolIsEmpty(my_pool))
81  cc_barrier();
82 }
83 
84 /** \brief Wait until we have the requested amount of packets in the pool
85  *
86  * In some cases waiting for packets is undesirable. Especially when
87  * a wait would happen under a lock of some kind, other parts of the
88  * engine could have to wait.
89  *
90  * This function only returns when at least N packets are in our pool.
91  *
92  * If counting in our pool's main stack didn't give us the number we
93  * are seeking, we check if the return stack is filled and add those
94  * to our main stack. Then we retry.
95  *
96  * \param n number of packets needed
97  */
98 void PacketPoolWaitForN(int n)
99 {
100  PktPool *my_pool = GetThreadPacketPool();
101 
102  while (1) {
103  PacketPoolWait();
104 
105  /* count packets in our stack */
106  int i = 0;
107  Packet *p, *pp;
108  pp = p = my_pool->head;
109  while (p != NULL) {
110  if (++i == n)
111  return;
112 
113  pp = p;
114  p = p->next;
115  }
116 
117  /* check return stack, return to our pool and retry counting */
118  if (my_pool->return_stack.head != NULL) {
119  SCMutexLock(&my_pool->return_stack.mutex);
120  /* Move all the packets from the locked return stack to the local stack. */
121  if (pp) {
122  pp->next = my_pool->return_stack.head;
123  } else {
124  my_pool->head = my_pool->return_stack.head;
125  }
126  my_pool->return_stack.head = NULL;
127  SC_ATOMIC_RESET(my_pool->return_stack.sync_now);
128  SCMutexUnlock(&my_pool->return_stack.mutex);
129 
130  /* or signal that we need packets and wait */
131  } else {
132  SCMutexLock(&my_pool->return_stack.mutex);
133  SC_ATOMIC_ADD(my_pool->return_stack.sync_now, 1);
134  SCCondWait(&my_pool->return_stack.cond, &my_pool->return_stack.mutex);
135  SCMutexUnlock(&my_pool->return_stack.mutex);
136  }
137  }
138 }
139 
140 /** \brief a initialized packet
141  *
142  * \warning Use *only* at init, not at packet runtime
143  */
144 static void PacketPoolStorePacket(Packet *p)
145 {
146  p->pool = GetThreadPacketPool();
149 }
150 
151 static void PacketPoolGetReturnedPackets(PktPool *pool)
152 {
153  SCMutexLock(&pool->return_stack.mutex);
154  /* Move all the packets from the locked return stack to the local stack. */
155  pool->head = pool->return_stack.head;
156  pool->return_stack.head = NULL;
157  SCMutexUnlock(&pool->return_stack.mutex);
158 }
159 
160 /** \brief Get a new packet from the packet pool
161  *
162  * Only allocates from the thread's local stack, or mallocs new packets.
163  * If the local stack is empty, first move all the return stack packets to
164  * the local stack.
165  * \retval Packet pointer, or NULL on failure.
166  */
168 {
169  PktPool *pool = GetThreadPacketPool();
170 #ifdef DEBUG_VALIDATION
171  BUG_ON(pool->initialized == 0);
172  BUG_ON(pool->destroyed == 1);
173 #endif /* DEBUG_VALIDATION */
174  if (pool->head) {
175  /* Stack is not empty. */
176  Packet *p = pool->head;
177  pool->head = p->next;
178  p->pool = pool;
179  PacketReinit(p);
180  return p;
181  }
182 
183  /* Local Stack is empty, so check the return stack, which requires
184  * locking. */
185  PacketPoolGetReturnedPackets(pool);
186 
187  /* Try to allocate again. Need to check for not empty again, since the
188  * return stack might have been empty too.
189  */
190  if (pool->head) {
191  /* Stack is not empty. */
192  Packet *p = pool->head;
193  pool->head = p->next;
194  p->pool = pool;
195  PacketReinit(p);
196  return p;
197  }
198 
199  /* Failed to allocate a packet, so return NULL. */
200  /* Optionally, could allocate a new packet here. */
201  return NULL;
202 }
203 
204 /** \brief Return packet to Packet pool
205  *
206  */
208 {
209  PktPool *my_pool = GetThreadPacketPool();
210  PktPool *pool = p->pool;
211  if (pool == NULL) {
212  PacketFree(p);
213  return;
214  }
215 
217 
218 #ifdef DEBUG_VALIDATION
219  BUG_ON(pool->initialized == 0);
220  BUG_ON(pool->destroyed == 1);
221  BUG_ON(my_pool->initialized == 0);
222  BUG_ON(my_pool->destroyed == 1);
223 #endif /* DEBUG_VALIDATION */
224 
225  if (pool == my_pool) {
226  /* Push back onto this thread's own stack, so no locking. */
227  p->next = my_pool->head;
228  my_pool->head = p;
229  } else {
230  PktPool *pending_pool = my_pool->pending_pool;
231  if (pending_pool == NULL) {
232  /* No pending packet, so store the current packet. */
233  p->next = NULL;
234  my_pool->pending_pool = pool;
235  my_pool->pending_head = p;
236  my_pool->pending_tail = p;
237  my_pool->pending_count = 1;
238  } else if (pending_pool == pool) {
239  /* Another packet for the pending pool list. */
240  p->next = my_pool->pending_head;
241  my_pool->pending_head = p;
242  my_pool->pending_count++;
243  if (SC_ATOMIC_GET(pool->return_stack.sync_now) || my_pool->pending_count > max_pending_return_packets) {
244  /* Return the entire list of pending packets. */
245  SCMutexLock(&pool->return_stack.mutex);
246  my_pool->pending_tail->next = pool->return_stack.head;
247  pool->return_stack.head = my_pool->pending_head;
248  SC_ATOMIC_RESET(pool->return_stack.sync_now);
249  SCMutexUnlock(&pool->return_stack.mutex);
250  SCCondSignal(&pool->return_stack.cond);
251  /* Clear the list of pending packets to return. */
252  my_pool->pending_pool = NULL;
253  my_pool->pending_head = NULL;
254  my_pool->pending_tail = NULL;
255  my_pool->pending_count = 0;
256  }
257  } else {
258  /* Push onto return stack for this pool */
259  SCMutexLock(&pool->return_stack.mutex);
260  p->next = pool->return_stack.head;
261  pool->return_stack.head = p;
262  SC_ATOMIC_RESET(pool->return_stack.sync_now);
263  SCMutexUnlock(&pool->return_stack.mutex);
264  SCCondSignal(&pool->return_stack.cond);
265  }
266  }
267 }
268 
270 {
271  PktPool *my_pool = GetThreadPacketPool();
272 
273 #ifdef DEBUG_VALIDATION
274  BUG_ON(my_pool->initialized);
275  my_pool->initialized = 1;
276  my_pool->destroyed = 0;
277 #endif /* DEBUG_VALIDATION */
278 
279  SCMutexInit(&my_pool->return_stack.mutex, NULL);
280  SCCondInit(&my_pool->return_stack.cond, NULL);
281  SC_ATOMIC_INIT(my_pool->return_stack.sync_now);
282 }
283 
284 void PacketPoolInit(void)
285 {
286  extern intmax_t max_pending_packets;
287 
288  PktPool *my_pool = GetThreadPacketPool();
289 
290 #ifdef DEBUG_VALIDATION
291  BUG_ON(my_pool->initialized);
292  my_pool->initialized = 1;
293  my_pool->destroyed = 0;
294 #endif /* DEBUG_VALIDATION */
295 
296  SCMutexInit(&my_pool->return_stack.mutex, NULL);
297  SCCondInit(&my_pool->return_stack.cond, NULL);
298  SC_ATOMIC_INIT(my_pool->return_stack.sync_now);
299 
300  /* pre allocate packets */
301  SCLogDebug("preallocating packets... packet size %" PRIuMAX "",
302  (uintmax_t)SIZE_OF_PACKET);
303  int i = 0;
304  for (i = 0; i < max_pending_packets; i++) {
305  Packet *p = PacketGetFromAlloc();
306  if (unlikely(p == NULL)) {
308  "Fatal error encountered while allocating a packet. Exiting...");
309  }
310  PacketPoolStorePacket(p);
311  }
312 
313  //SCLogInfo("preallocated %"PRIiMAX" packets. Total memory %"PRIuMAX"",
314  // max_pending_packets, (uintmax_t)(max_pending_packets*SIZE_OF_PACKET));
315 }
316 
318 {
319  Packet *p = NULL;
320  PktPool *my_pool = GetThreadPacketPool();
321 
322 #ifdef DEBUG_VALIDATION
323  BUG_ON(my_pool && my_pool->destroyed);
324 #endif /* DEBUG_VALIDATION */
325 
326  if (my_pool && my_pool->pending_pool != NULL) {
327  p = my_pool->pending_head;
328  while (p) {
329  Packet *next_p = p->next;
330  PacketFree(p);
331  p = next_p;
332  my_pool->pending_count--;
333  }
334 #ifdef DEBUG_VALIDATION
335  BUG_ON(my_pool->pending_count);
336 #endif /* DEBUG_VALIDATION */
337  my_pool->pending_pool = NULL;
338  my_pool->pending_head = NULL;
339  my_pool->pending_tail = NULL;
340  }
341 
342  while ((p = PacketPoolGetPacket()) != NULL) {
343  PacketFree(p);
344  }
345 
346 #ifdef DEBUG_VALIDATION
347  my_pool->initialized = 0;
348  my_pool->destroyed = 1;
349 #endif /* DEBUG_VALIDATION */
350 }
351 
353 {
354  return PacketPoolGetPacket();
355 }
356 
358 {
359  bool proot = false;
360 
361  SCEnter();
362  SCLogDebug("Packet %p, p->root %p, alloced %s", p, p->root, BOOL2STR(p->pool == NULL));
363 
364  if (IS_TUNNEL_PKT(p)) {
365  SCLogDebug("Packet %p is a tunnel packet: %s",
366  p,p->root ? "upper layer" : "tunnel root");
367 
368  /* get a lock to access root packet fields */
370  SCSpinLock(lock);
371 
372  if (IS_TUNNEL_ROOT_PKT(p)) {
373  SCLogDebug("IS_TUNNEL_ROOT_PKT == TRUE");
374  const uint16_t outstanding = TUNNEL_PKT_TPR(p) - TUNNEL_PKT_RTV(p);
375  SCLogDebug("root pkt: outstanding %u", outstanding);
376  if (outstanding == 0) {
377  SCLogDebug("no tunnel packets outstanding, no more tunnel "
378  "packet(s) depending on this root");
379  /* if this packet is the root and there are no
380  * more tunnel packets to consider
381  *
382  * return it to the pool */
383  } else {
384  SCLogDebug("tunnel root Packet %p: outstanding > 0, so "
385  "packets are still depending on this root, setting "
386  "SET_TUNNEL_PKT_VERDICTED", p);
387  /* if this is the root and there are more tunnel
388  * packets, return this to the pool. It's still referenced
389  * by the tunnel packets, and we will return it
390  * when we handle them */
392 
395  SCReturn;
396  }
397  } else {
398  SCLogDebug("NOT IS_TUNNEL_ROOT_PKT, so tunnel pkt");
399 
401  const uint16_t outstanding = TUNNEL_PKT_TPR(p) - TUNNEL_PKT_RTV(p);
402  SCLogDebug("tunnel pkt: outstanding %u", outstanding);
403  /* all tunnel packets are processed except us. Root already
404  * processed. So return tunnel pkt and root packet to the
405  * pool. */
406  if (outstanding == 0 &&
408  {
409  SCLogDebug("root verdicted == true && no outstanding");
410 
411  /* handle freeing the root as well*/
412  SCLogDebug("setting proot = 1 for root pkt, p->root %p "
413  "(tunnel packet %p)", p->root, p);
414  proot = true;
415 
416  /* fall through */
417 
418  } else {
419  /* root not ready yet, or not the last tunnel packet,
420  * so get rid of the tunnel pkt only */
421 
422  SCLogDebug("NOT IS_TUNNEL_PKT_VERDICTED (%s) || "
423  "outstanding > 0 (%u)",
424  (p->root && IS_TUNNEL_PKT_VERDICTED(p->root)) ? "true" : "false",
425  outstanding);
426 
427  /* fall through */
428  }
429  }
431 
432  SCLogDebug("tunnel stuff done, move on (proot %d)", proot);
433  }
434 
435  SCLogDebug("[packet %p][%s] %s", p,
436  IS_TUNNEL_PKT(p) ? IS_TUNNEL_ROOT_PKT(p) ? "tunnel::root" : "tunnel::leaf"
437  : "no tunnel",
438  (p->action & ACTION_DROP) ? "DROP" : "no drop");
439 
440  /* we're done with the tunnel root now as well */
441  if (proot == true) {
442  SCLogDebug("getting rid of root pkt... alloc'd %s", BOOL2STR(p->root->pool == NULL));
443 
445  p->root->ReleasePacket(p->root);
446  p->root = NULL;
447  }
448 
450 
452  p->ReleasePacket(p);
453 
454  SCReturn;
455 }
456 
457 /**
458  * \brief Release all the packets in the queue back to the packetpool. Mainly
459  * used by threads that have failed, and wants to return the packets back
460  * to the packetpool.
461  *
462  * \param pq Pointer to the packetqueue from which the packets have to be
463  * returned back to the packetpool
464  *
465  * \warning this function assumes that the pq does not use locking
466  */
468 {
469  Packet *p = NULL;
470 
471  if (pq == NULL)
472  return;
473 
474  while ( (p = PacketDequeue(pq)) != NULL)
475  TmqhOutputPacketpool(NULL, p);
476 
477  return;
478 }
479 
480 /** number of packets to keep reserved when calculating the the pending
481  * return packets count. This assumes we need at max 10 packets in one
482  * PacketPoolWaitForN call. The actual number is 9 now, so this has a
483  * bit of margin. */
484 #define RESERVED_PACKETS 10
485 
486 /**
487  * \brief Set the max_pending_return_packets value
488  *
489  * Set it to the max pending packets value, devided by the number
490  * of lister threads. Normally, in autofp these are the stream/detect/log
491  * worker threads.
492  *
493  * The max_pending_return_packets value needs to stay below the packet
494  * pool size of the 'producers' (normally pkt capture threads but also
495  * flow timeout injection ) to avoid a deadlock where all the 'workers'
496  * keep packets in their return pools, while the capture thread can't
497  * continue because its pool is empty.
498  */
500 {
501  extern intmax_t max_pending_packets;
502  intmax_t pending_packets = max_pending_packets;
503  if (pending_packets < RESERVED_PACKETS) {
504  FatalError(SC_ERR_INVALID_ARGUMENT, "'max-pending-packets' setting "
505  "must be at least %d", RESERVED_PACKETS);
506  }
508  if (threads == 0)
509  return;
510 
511  uint32_t packets = (pending_packets / threads) - 1;
512  if (packets < max_pending_return_packets)
513  max_pending_return_packets = packets;
514 
515  /* make sure to have a margin in the return logic */
516  if (max_pending_return_packets >= RESERVED_PACKETS)
517  max_pending_return_packets -= RESERVED_PACKETS;
518 
519  SCLogDebug("detect threads %u, max packets %u, max_pending_return_packets %u",
520  threads, packets, max_pending_return_packets);
521 }
tm-threads.h
PktPool_::pending_tail
Packet * pending_tail
Definition: tmqh-packetpool.h:51
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
Definition: util-atomic.h:315
PacketPoolReturnPacket
void PacketPoolReturnPacket(Packet *p)
Return packet to Packet pool.
Definition: tmqh-packetpool.c:207
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
PktPool_
Definition: tmqh-packetpool.h:39
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:296
RESERVED_PACKETS
#define RESERVED_PACKETS
Definition: tmqh-packetpool.c:484
TM_FLAG_DETECT_TM
#define TM_FLAG_DETECT_TM
Definition: tm-modules.h:34
PacketQueue_
simple fifo queue for packets with mutex and cond Calling the mutex or triggering the cond is respons...
Definition: packet-queue.h:49
action-globals.h
Packet_::action
uint8_t action
Definition: decode.h:571
threads.h
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:333
Tmqh_::OutHandler
void(* OutHandler)(ThreadVars *, Packet *)
Definition: tm-queuehandlers.h:40
Packet_::pool
struct PktPool_ * pool
Definition: decode.h:629
PacketReleaseRefs
void PacketReleaseRefs(Packet *p)
Definition: packet.c:70
SCCondInit
#define SCCondInit
Definition: threads-debug.h:138
IS_TUNNEL_ROOT_PKT
#define IS_TUNNEL_ROOT_PKT(p)
Definition: decode.h:793
TmThreadCountThreadsByTmmFlags
uint32_t TmThreadCountThreadsByTmmFlags(uint8_t flags)
returns a count of all the threads that match the flag
Definition: tm-threads.c:1993
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
tm-modules.h
SCSpinLock
#define SCSpinLock
Definition: threads-debug.h:235
PktPool_::pending_count
uint32_t pending_count
Definition: tmqh-packetpool.h:52
PacketPoolPostRunmodes
void PacketPoolPostRunmodes(void)
Set the max_pending_return_packets value.
Definition: tmqh-packetpool.c:499
MAX_PENDING_RETURN_PACKETS
#define MAX_PENDING_RETURN_PACKETS
Definition: tmqh-packetpool.c:39
TmqhOutputPacketpool
void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
Definition: tmqh-packetpool.c:357
Packet_::persistent
struct Packet_::@42 persistent
tmqh-packetpool.h
thread_pkt_pool
thread_local PktPool thread_pkt_pool
Definition: tmqh-packetpool.c:42
PktPool_::pending_head
Packet * pending_head
Definition: tmqh-packetpool.h:50
TmqhReleasePacketsToPacketPool
void TmqhReleasePacketsToPacketPool(PacketQueue *pq)
Release all the packets in the queue back to the packetpool. Mainly used by threads that have failed,...
Definition: tmqh-packetpool.c:467
PacketPoolInit
void PacketPoolInit(void)
Definition: tmqh-packetpool.c:284
Tmqh_::InHandler
Packet *(* InHandler)(ThreadVars *)
Definition: tm-queuehandlers.h:38
lock
HRLOCK_TYPE lock
Definition: host.h:0
decode.h
TUNNEL_PKT_TPR
#define TUNNEL_PKT_TPR(p)
Definition: decode.h:788
PacketReinit
void PacketReinit(Packet *p)
Recycle a packet structure for reuse.
Definition: packet.c:80
SCCondWait
#define SCCondWait
Definition: threads-debug.h:141
Packet_::tunnel_lock
SCSpinlock tunnel_lock
Definition: decode.h:642
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
TMQH_PACKETPOOL
@ TMQH_PACKETPOOL
Definition: tm-queuehandlers.h:30
BOOL2STR
#define BOOL2STR(b)
Definition: util-debug.h:554
IS_TUNNEL_PKT_VERDICTED
#define IS_TUNNEL_PKT_VERDICTED(p)
Definition: decode.h:795
SCEnter
#define SCEnter(...)
Definition: util-debug.h:298
PacketPoolWaitForN
void PacketPoolWaitForN(int n)
Wait until we have the requested amount of packets in the pool.
Definition: tmqh-packetpool.c:98
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
PacketFree
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:134
SCSpinUnlock
#define SCSpinUnlock
Definition: threads-debug.h:237
TmqhInputPacketpool
Packet * TmqhInputPacketpool(ThreadVars *tv)
Definition: tmqh-packetpool.c:352
SIZE_OF_PACKET
#define SIZE_OF_PACKET
Definition: decode.h:655
SC_ERR_INVALID_ARGUMENT
@ SC_ERR_INVALID_ARGUMENT
Definition: util-error.h:43
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:289
util-profiling.h
PacketPoolWait
void PacketPoolWait(void)
Definition: tmqh-packetpool.c:69
SCReturn
#define SCReturn
Definition: util-debug.h:300
Packet_
Definition: decode.h:425
Tmqh_::name
const char * name
Definition: tm-queuehandlers.h:37
IS_TUNNEL_PKT
#define IS_TUNNEL_PKT(p)
Definition: decode.h:790
SET_TUNNEL_PKT_VERDICTED
#define SET_TUNNEL_PKT_VERDICTED(p)
Definition: decode.h:796
SCMutexInit
#define SCMutexInit(mut, mutattrs)
Definition: threads-debug.h:116
PktPool_::return_stack
PktPoolLockedStack return_stack
Definition: tmqh-packetpool.h:66
tm-queuehandlers.h
TmqhPacketpoolRegister
void TmqhPacketpoolRegister(void)
TmqhPacketpoolRegister \initonly.
Definition: tmqh-packetpool.c:53
Packet_::ReleasePacket
void(* ReleasePacket)(struct Packet_ *)
Definition: decode.h:509
SCCondSignal
#define SCCondSignal
Definition: threads-debug.h:139
suricata-common.h
packet.h
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
FatalError
#define FatalError(x,...)
Definition: util-debug.h:530
tmqh_table
Tmqh tmqh_table[TMQH_SIZE]
Definition: tm-queuehandlers.c:37
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
SC_ATOMIC_RESET
#define SC_ATOMIC_RESET(name)
wrapper for reinitializing an atomic variable.
Definition: util-atomic.h:324
PacketDequeue
Packet * PacketDequeue(PacketQueue *q)
Definition: packet-queue.c:212
util-validate.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:173
TUNNEL_PKT_RTV
#define TUNNEL_PKT_RTV(p)
Definition: decode.h:787
Packet_::next
struct Packet_ * next
Definition: decode.h:597
Packet_::root
struct Packet_ * root
Definition: decode.h:612
max_pending_packets
int max_pending_packets
Definition: suricata.c:175
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
TUNNEL_INCR_PKT_RTV_NOLOCK
#define TUNNEL_INCR_PKT_RTV_NOLOCK(p)
Definition: decode.h:775
PACKET_PROFILING_END
#define PACKET_PROFILING_END(p)
Definition: util-profiling.h:106
PacketPoolGetPacket
Packet * PacketPoolGetPacket(void)
Get a new packet from the packet pool.
Definition: tmqh-packetpool.c:167
SCSpinlock
#define SCSpinlock
Definition: threads-debug.h:234
PacketPoolInitEmpty
void PacketPoolInitEmpty(void)
Definition: tmqh-packetpool.c:269
cc_barrier
#define cc_barrier()
Definition: util-optimize.h:43
PktPool_::pending_pool
struct PktPool_ * pending_pool
Definition: tmqh-packetpool.h:49
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:376
PacketPoolDestroy
void PacketPoolDestroy(void)
Definition: tmqh-packetpool.c:317
PktPool_::head
Packet * head
Definition: tmqh-packetpool.h:43