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)) {
307  FatalError("Fatal error encountered while allocating a packet. Exiting...");
308  }
309  PacketPoolStorePacket(p);
310  }
311 
312  //SCLogInfo("preallocated %"PRIiMAX" packets. Total memory %"PRIuMAX"",
313  // max_pending_packets, (uintmax_t)(max_pending_packets*SIZE_OF_PACKET));
314 }
315 
317 {
318  Packet *p = NULL;
319  PktPool *my_pool = GetThreadPacketPool();
320 
321 #ifdef DEBUG_VALIDATION
322  BUG_ON(my_pool && my_pool->destroyed);
323 #endif /* DEBUG_VALIDATION */
324 
325  if (my_pool && my_pool->pending_pool != NULL) {
326  p = my_pool->pending_head;
327  while (p) {
328  Packet *next_p = p->next;
329  PacketFree(p);
330  p = next_p;
331  my_pool->pending_count--;
332  }
333 #ifdef DEBUG_VALIDATION
334  BUG_ON(my_pool->pending_count);
335 #endif /* DEBUG_VALIDATION */
336  my_pool->pending_pool = NULL;
337  my_pool->pending_head = NULL;
338  my_pool->pending_tail = NULL;
339  }
340 
341  while ((p = PacketPoolGetPacket()) != NULL) {
342  PacketFree(p);
343  }
344 
345 #ifdef DEBUG_VALIDATION
346  my_pool->initialized = 0;
347  my_pool->destroyed = 1;
348 #endif /* DEBUG_VALIDATION */
349 }
350 
352 {
353  return PacketPoolGetPacket();
354 }
355 
357 {
358  bool proot = false;
359 
360  SCEnter();
361  SCLogDebug("Packet %p, p->root %p, alloced %s", p, p->root, BOOL2STR(p->pool == NULL));
362 
363  if (IS_TUNNEL_PKT(p)) {
364  SCLogDebug("Packet %p is a tunnel packet: %s",
365  p,p->root ? "upper layer" : "tunnel root");
366 
367  /* get a lock to access root packet fields */
369  SCSpinLock(lock);
370 
371  if (IS_TUNNEL_ROOT_PKT(p)) {
372  SCLogDebug("IS_TUNNEL_ROOT_PKT == TRUE");
373  const uint16_t outstanding = TUNNEL_PKT_TPR(p) - TUNNEL_PKT_RTV(p);
374  SCLogDebug("root pkt: outstanding %u", outstanding);
375  if (outstanding == 0) {
376  SCLogDebug("no tunnel packets outstanding, no more tunnel "
377  "packet(s) depending on this root");
378  /* if this packet is the root and there are no
379  * more tunnel packets to consider
380  *
381  * return it to the pool */
382  } else {
383  SCLogDebug("tunnel root Packet %p: outstanding > 0, so "
384  "packets are still depending on this root, setting "
385  "SET_TUNNEL_PKT_VERDICTED", p);
386  /* if this is the root and there are more tunnel
387  * packets, return this to the pool. It's still referenced
388  * by the tunnel packets, and we will return it
389  * when we handle them */
391 
394  SCReturn;
395  }
396  } else {
397  SCLogDebug("NOT IS_TUNNEL_ROOT_PKT, so tunnel pkt");
398 
400  const uint16_t outstanding = TUNNEL_PKT_TPR(p) - TUNNEL_PKT_RTV(p);
401  SCLogDebug("tunnel pkt: outstanding %u", outstanding);
402  /* all tunnel packets are processed except us. Root already
403  * processed. So return tunnel pkt and root packet to the
404  * pool. */
405  if (outstanding == 0 &&
407  {
408  SCLogDebug("root verdicted == true && no outstanding");
409 
410  /* handle freeing the root as well*/
411  SCLogDebug("setting proot = 1 for root pkt, p->root %p "
412  "(tunnel packet %p)", p->root, p);
413  proot = true;
414 
415  /* fall through */
416 
417  } else {
418  /* root not ready yet, or not the last tunnel packet,
419  * so get rid of the tunnel pkt only */
420 
421  SCLogDebug("NOT IS_TUNNEL_PKT_VERDICTED (%s) || "
422  "outstanding > 0 (%u)",
423  (p->root && IS_TUNNEL_PKT_VERDICTED(p->root)) ? "true" : "false",
424  outstanding);
425 
426  /* fall through */
427  }
428  }
430 
431  SCLogDebug("tunnel stuff done, move on (proot %d)", proot);
432  }
433 
434  SCLogDebug("[packet %p][%s] %s", p,
435  IS_TUNNEL_PKT(p) ? IS_TUNNEL_ROOT_PKT(p) ? "tunnel::root" : "tunnel::leaf"
436  : "no tunnel",
437  (p->action & ACTION_DROP) ? "DROP" : "no drop");
438 
439  /* we're done with the tunnel root now as well */
440  if (proot == true) {
441  SCLogDebug("getting rid of root pkt... alloc'd %s", BOOL2STR(p->root->pool == NULL));
442 
444  p->root->ReleasePacket(p->root);
445  p->root = NULL;
446  }
447 
449 
451  p->ReleasePacket(p);
452 
453  SCReturn;
454 }
455 
456 /**
457  * \brief Release all the packets in the queue back to the packetpool. Mainly
458  * used by threads that have failed, and wants to return the packets back
459  * to the packetpool.
460  *
461  * \param pq Pointer to the packetqueue from which the packets have to be
462  * returned back to the packetpool
463  *
464  * \warning this function assumes that the pq does not use locking
465  */
467 {
468  Packet *p = NULL;
469 
470  if (pq == NULL)
471  return;
472 
473  while ((p = PacketDequeue(pq)) != NULL) {
474  DEBUG_VALIDATE_BUG_ON(p->flow != NULL);
475  TmqhOutputPacketpool(NULL, p);
476  }
477 
478  return;
479 }
480 
481 /** number of packets to keep reserved when calculating the the pending
482  * return packets count. This assumes we need at max 10 packets in one
483  * PacketPoolWaitForN call. The actual number is 9 now, so this has a
484  * bit of margin. */
485 #define RESERVED_PACKETS 10
486 
487 /**
488  * \brief Set the max_pending_return_packets value
489  *
490  * Set it to the max pending packets value, devided by the number
491  * of lister threads. Normally, in autofp these are the stream/detect/log
492  * worker threads.
493  *
494  * The max_pending_return_packets value needs to stay below the packet
495  * pool size of the 'producers' (normally pkt capture threads but also
496  * flow timeout injection ) to avoid a deadlock where all the 'workers'
497  * keep packets in their return pools, while the capture thread can't
498  * continue because its pool is empty.
499  */
501 {
502  extern intmax_t max_pending_packets;
503  intmax_t pending_packets = max_pending_packets;
504  if (pending_packets < RESERVED_PACKETS) {
505  FatalError("'max-pending-packets' setting "
506  "must be at least %d",
508  }
510  if (threads == 0)
511  return;
512 
513  uint32_t packets = (pending_packets / threads) - 1;
514  if (packets < max_pending_return_packets)
515  max_pending_return_packets = packets;
516 
517  /* make sure to have a margin in the return logic */
518  if (max_pending_return_packets >= RESERVED_PACKETS)
519  max_pending_return_packets -= RESERVED_PACKETS;
520 
521  SCLogDebug("detect threads %u, max packets %u, max_pending_return_packets %u",
522  threads, packets, max_pending_return_packets);
523 }
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:269
RESERVED_PACKETS
#define RESERVED_PACKETS
Definition: tmqh-packetpool.c:485
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:577
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:635
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:800
TmThreadCountThreadsByTmmFlags
uint32_t TmThreadCountThreadsByTmmFlags(uint8_t flags)
returns a count of all the threads that match the flag
Definition: tm-threads.c:1996
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:500
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:356
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:466
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:795
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:648
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
BOOL2STR
#define BOOL2STR(b)
Definition: util-debug.h:527
IS_TUNNEL_PKT_VERDICTED
#define IS_TUNNEL_PKT_VERDICTED(p)
Definition: decode.h:802
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
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:351
SIZE_OF_PACKET
#define SIZE_OF_PACKET
Definition: decode.h:660
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:273
Packet_
Definition: decode.h:428
Tmqh_::name
const char * name
Definition: tm-queuehandlers.h:37
TMQH_PACKETPOOL
@ TMQH_PACKETPOOL
Definition: tm-queuehandlers.h:30
IS_TUNNEL_PKT
#define IS_TUNNEL_PKT(p)
Definition: decode.h:797
Packet_::persistent
struct Packet_::@41 persistent
SET_TUNNEL_PKT_VERDICTED
#define SET_TUNNEL_PKT_VERDICTED(p)
Definition: decode.h:803
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:515
SCCondSignal
#define SCCondSignal
Definition: threads-debug.h:139
Packet_::flow
struct Flow_ * flow
Definition: decode.h:465
suricata-common.h
packet.h
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
FatalError
#define FatalError(...)
Definition: util-debug.h:502
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:794
Packet_::next
struct Packet_ * next
Definition: decode.h:603
Packet_::root
struct Packet_ * root
Definition: decode.h:618
max_pending_packets
int max_pending_packets
Definition: suricata.c:178
TUNNEL_INCR_PKT_RTV_NOLOCK
#define TUNNEL_INCR_PKT_RTV_NOLOCK(p)
Definition: decode.h:782
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:316
PktPool_::head
Packet * head
Definition: tmqh-packetpool.h:43
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111