Skip to content

Commit 31bbe65

Browse files
jasonishclaude
andcommitted
packet pool: attach to ThreadVars for multi-instance support
Move packet pools from thread-local storage to ThreadVars structure to enable multi-instance Suricata support. Thread-local storage is process-wide and cannot be isolated per instance. This implementation uses a simplified approach where packets are returned directly to their origin pool (via p->pool) with mutex locking. The previous batching optimizations that used thread-local pending pools have been removed in favor of code simplicity. Changes: - Add pkt_pool pointer to ThreadVars - Add tv back-pointer to PktPool - Update PacketPoolGetPacket/PacketPoolWait to accept ThreadVars parameter - Update PacketGetFromQueueOrAlloc to accept ThreadVars parameter - Update PacketDefragPktSetup to accept ThreadVars parameter - Update FlowPseudoPacketGet to accept ThreadVars parameter - Add PacketPoolInitThreaded/PacketPoolDestroyThreaded functions - Remove thread-local current_tv and pending pool batching logic - Update all call sites across source files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent a16e87b commit 31bbe65

26 files changed

Lines changed: 148 additions & 121 deletions

examples/plugins/ci-capture/source.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static TmEcode ReceiveLoop(ThreadVars *tv, void *data, void *slot)
6565
/* Notify we are running and processing packets. */
6666
TmThreadsSetFlag(tv, THV_RUNNING);
6767

68-
PacketPoolWait();
68+
PacketPoolWait(ptv->tv);
6969
Packet *p = PacketGetFromQueueOrAlloc();
7070
if (unlikely(p == NULL)) {
7171
return TM_ECODE_FAILED;

plugins/napatech/source-napatech.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ TmEcode NapatechPacketLoop(ThreadVars *tv, void *data, void *slot)
847847
while (!(suricata_ctl_flags & SURICATA_STOP)) {
848848
/* make sure we have at least one packet in the packet pool, to prevent
849849
* us from alloc'ing packets at line rate */
850-
PacketPoolWait();
850+
PacketPoolWait(ptv->tv);
851851

852852
/* Napatech returns packets 1 at a time */
853853
status = NT_NetRxGet(ntv->rx_stream, &packet_buffer, 1000);

plugins/pfring/source-pfring.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot)
330330

331331
/* make sure we have at least one packet in the packet pool, to prevent
332332
* us from alloc'ing packets at line rate */
333-
PacketPoolWait();
333+
PacketPoolWait(ptv->tv);
334334

335335
p = PacketGetFromQueueOrAlloc();
336336
if (p == NULL) {

src/decode.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,10 @@ void PacketFreeOrRelease(Packet *p)
290290
*
291291
* \retval p packet, NULL on error
292292
*/
293-
Packet *PacketGetFromQueueOrAlloc(void)
293+
Packet *PacketGetFromQueueOrAlloc(ThreadVars *tv)
294294
{
295295
/* try the pool first */
296-
Packet *p = PacketPoolGetPacket();
296+
Packet *p = PacketPoolGetPacket(tv);
297297

298298
if (p == NULL) {
299299
/* non fatal, we're just not processing a packet then */
@@ -403,7 +403,7 @@ Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *pare
403403
}
404404

405405
/* get us a packet */
406-
Packet *p = PacketGetFromQueueOrAlloc();
406+
Packet *p = PacketGetFromQueueOrAlloc(tv);
407407
if (unlikely(p == NULL)) {
408408
SCReturnPtr(NULL, "Packet");
409409
}
@@ -470,12 +470,12 @@ Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *pare
470470
*
471471
* \retval p the pseudo packet or NULL if out of memory
472472
*/
473-
Packet *PacketDefragPktSetup(Packet *parent, const uint8_t *pkt, uint32_t len, uint8_t proto)
473+
Packet *PacketDefragPktSetup(ThreadVars *tv, Packet *parent, const uint8_t *pkt, uint32_t len, uint8_t proto)
474474
{
475475
SCEnter();
476476

477477
/* get us a packet */
478-
Packet *p = PacketGetFromQueueOrAlloc();
478+
Packet *p = PacketGetFromQueueOrAlloc(tv);
479479
if (unlikely(p == NULL)) {
480480
SCReturnPtr(NULL, "Packet");
481481
}

src/decode.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,10 +1115,10 @@ enum DecodeTunnelProto {
11151115

11161116
Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *parent,
11171117
const uint8_t *pkt, uint32_t len, enum DecodeTunnelProto proto);
1118-
Packet *PacketDefragPktSetup(Packet *parent, const uint8_t *pkt, uint32_t len, uint8_t proto);
1118+
Packet *PacketDefragPktSetup(ThreadVars *tv, Packet *parent, const uint8_t *pkt, uint32_t len, uint8_t proto);
11191119
void PacketDefragPktSetupParent(Packet *parent);
11201120
void DecodeRegisterPerfCounters(DecodeThreadVars *, ThreadVars *);
1121-
Packet *PacketGetFromQueueOrAlloc(void);
1121+
Packet *PacketGetFromQueueOrAlloc(ThreadVars *);
11221122
Packet *PacketGetFromAlloc(void);
11231123
void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p);
11241124
void PacketUpdateEngineEventCounters(ThreadVars *tv,

src/defrag.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ Defrag4Reassemble(ThreadVars *tv, DefragTracker *tracker, Packet *p)
263263

264264
/* Allocate a Packet for the reassembled packet. On failure we
265265
* SCFree all the resources held by this tracker. */
266-
rp = PacketDefragPktSetup(p, NULL, 0, IPV4_GET_RAW_IPPROTO(oip4h));
266+
rp = PacketDefragPktSetup(tv, p, NULL, 0, IPV4_GET_RAW_IPPROTO(oip4h));
267267
if (rp == NULL) {
268268
goto error_remove_tracker;
269269
}
@@ -424,7 +424,7 @@ Defrag6Reassemble(ThreadVars *tv, DefragTracker *tracker, Packet *p)
424424
/* Allocate a Packet for the reassembled packet. On failure we
425425
* SCFree all the resources held by this tracker. */
426426
rp = PacketDefragPktSetup(
427-
p, (const uint8_t *)oip6h, IPV6_GET_RAW_PLEN(oip6h) + sizeof(IPV6Hdr), 0);
427+
tv, p, (const uint8_t *)oip6h, IPV6_GET_RAW_PLEN(oip6h) + sizeof(IPV6Hdr), 0);
428428
if (rp == NULL) {
429429
goto error_remove_tracker;
430430
}

src/flow-timeout.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,10 @@ static inline Packet *FlowPseudoPacketSetup(
261261
return NULL;
262262
}
263263

264-
Packet *FlowPseudoPacketGet(int direction, Flow *f, const TcpSession *ssn)
264+
Packet *FlowPseudoPacketGet(ThreadVars *tv, int direction, Flow *f, const TcpSession *ssn)
265265
{
266-
PacketPoolWait();
267-
Packet *p = PacketPoolGetPacket();
266+
PacketPoolWait(tv);
267+
Packet *p = PacketPoolGetPacket(tv);
268268
if (p == NULL) {
269269
return NULL;
270270
}

src/flow-timeout.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@
2929
void FlowSendToLocalThread(Flow *f);
3030
bool FlowNeedsReassembly(Flow *f);
3131
void FlowWorkToDoCleanup(void);
32-
Packet *FlowPseudoPacketGet(int direction, Flow *f, const TcpSession *ssn);
32+
Packet *FlowPseudoPacketGet(ThreadVars *tv, int direction, Flow *f, const TcpSession *ssn);
3333

3434
#endif /* SURICATA_FLOW_TIMEOUT_H */

src/flow-worker.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static int FlowFinish(ThreadVars *tv, Flow *f, FlowWorkerThreadData *fw, void *d
122122

123123
/* insert a pseudo packet in the toserver direction */
124124
if (client == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION) {
125-
Packet *p = FlowPseudoPacketGet(0, f, ssn);
125+
Packet *p = FlowPseudoPacketGet(tv, 0, f, ssn);
126126
if (p != NULL) {
127127
PKT_SET_SRC(p, PKT_SRC_FFR);
128128
if (server == STREAM_HAS_UNPROCESSED_SEGMENTS_NONE) {
@@ -136,7 +136,7 @@ static int FlowFinish(ThreadVars *tv, Flow *f, FlowWorkerThreadData *fw, void *d
136136

137137
/* handle toclient */
138138
if (server == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION) {
139-
Packet *p = FlowPseudoPacketGet(1, f, ssn);
139+
Packet *p = FlowPseudoPacketGet(tv, 1, f, ssn);
140140
if (p != NULL) {
141141
PKT_SET_SRC(p, PKT_SRC_FFR);
142142
p->flowflags |= FLOW_PKT_LAST_PSEUDO;

src/source-af-packet.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -926,7 +926,7 @@ static int AFPReadFromRing(AFPThreadVars *ptv)
926926
if (unlikely(AFPShouldIgnoreFrame(ptv, sll)))
927927
goto next_frame;
928928

929-
Packet *p = PacketGetFromQueueOrAlloc();
929+
Packet *p = PacketGetFromQueueOrAlloc(ptv->tv);
930930
if (p == NULL) {
931931
return AFPSuriFailure(ptv, h);
932932
}
@@ -956,7 +956,7 @@ static inline void AFPFlushBlock(struct tpacket_block_desc *pbd)
956956

957957
static inline int AFPParsePacketV3(AFPThreadVars *ptv, struct tpacket_block_desc *pbd, struct tpacket3_hdr *ppd)
958958
{
959-
Packet *p = PacketGetFromQueueOrAlloc();
959+
Packet *p = PacketGetFromQueueOrAlloc(ptv->tv);
960960
if (p == NULL) {
961961
SCReturnInt(AFP_SURI_FAILURE);
962962
}
@@ -1387,7 +1387,7 @@ TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot)
13871387

13881388
/* make sure we have at least one packet in the packet pool, to prevent
13891389
* us from alloc'ing packets at line rate */
1390-
PacketPoolWait();
1390+
PacketPoolWait(ptv->tv);
13911391

13921392
StatsIncr(ptv->tv, ptv->capture_afp_poll);
13931393

0 commit comments

Comments
 (0)