From: cardigliano Date: Tue, 20 Oct 2015 16:24:25 +0000 (+0200) Subject: pkt acq: introduce break loop API X-Git-Tag: suricata-3.0.1RC1~74 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=57e0bd39e91f4edb72fb7be78d5c40682a188475;p=thirdparty%2Fsuricata.git pkt acq: introduce break loop API This patch adds a new callback PktAcqBreakLoop() in TmModule to let packet acquisition modules define "break-loop" functions to terminate the capture loop. This is useful in case of blocking functions that need special actions to take place in order to stop the execution. Implement this for PF_RING --- diff --git a/src/source-af-packet.c b/src/source-af-packet.c index f9eb865820..212e118424 100644 --- a/src/source-af-packet.c +++ b/src/source-af-packet.c @@ -271,6 +271,7 @@ void TmModuleReceiveAFPRegister (void) tmm_modules[TMM_RECEIVEAFP].ThreadInit = ReceiveAFPThreadInit; tmm_modules[TMM_RECEIVEAFP].Func = NULL; tmm_modules[TMM_RECEIVEAFP].PktAcqLoop = ReceiveAFPLoop; + tmm_modules[TMM_RECEIVEAFP].PktAcqBreakLoop = NULL; tmm_modules[TMM_RECEIVEAFP].ThreadExitPrintStats = ReceiveAFPThreadExitStats; tmm_modules[TMM_RECEIVEAFP].ThreadDeinit = NULL; tmm_modules[TMM_RECEIVEAFP].RegisterTests = NULL; diff --git a/src/source-erf-dag.c b/src/source-erf-dag.c index f66407122f..76f5fe3d83 100644 --- a/src/source-erf-dag.c +++ b/src/source-erf-dag.c @@ -138,6 +138,7 @@ TmModuleReceiveErfDagRegister(void) tmm_modules[TMM_RECEIVEERFDAG].ThreadInit = ReceiveErfDagThreadInit; tmm_modules[TMM_RECEIVEERFDAG].Func = NULL; tmm_modules[TMM_RECEIVEERFDAG].PktAcqLoop = ReceiveErfDagLoop; + tmm_modules[TMM_RECEIVEERFDAG].PktAcqBreakLoop = NULL; tmm_modules[TMM_RECEIVEERFDAG].ThreadExitPrintStats = ReceiveErfDagThreadExitStats; tmm_modules[TMM_RECEIVEERFDAG].ThreadDeinit = NULL; diff --git a/src/source-erf-file.c b/src/source-erf-file.c index 938621c40a..5d8af87f75 100644 --- a/src/source-erf-file.c +++ b/src/source-erf-file.c @@ -81,6 +81,7 @@ TmModuleReceiveErfFileRegister(void) tmm_modules[TMM_RECEIVEERFFILE].ThreadInit = ReceiveErfFileThreadInit; tmm_modules[TMM_RECEIVEERFFILE].Func = NULL; tmm_modules[TMM_RECEIVEERFFILE].PktAcqLoop = ReceiveErfFileLoop; + tmm_modules[TMM_RECEIVEERFFILE].PktAcqBreakLoop = NULL; tmm_modules[TMM_RECEIVEERFFILE].ThreadExitPrintStats = ReceiveErfFileThreadExitStats; tmm_modules[TMM_RECEIVEERFFILE].ThreadDeinit = NULL; diff --git a/src/source-ipfw.c b/src/source-ipfw.c index 4c68958bed..e3e0e4986e 100644 --- a/src/source-ipfw.c +++ b/src/source-ipfw.c @@ -158,6 +158,7 @@ void TmModuleReceiveIPFWRegister (void) tmm_modules[TMM_RECEIVEIPFW].ThreadInit = ReceiveIPFWThreadInit; tmm_modules[TMM_RECEIVEIPFW].Func = NULL; tmm_modules[TMM_RECEIVEIPFW].PktAcqLoop = ReceiveIPFWLoop; + tmm_modules[TMM_RECEIVEIPFW].PktAcqBreakLoop = NULL; tmm_modules[TMM_RECEIVEIPFW].ThreadExitPrintStats = ReceiveIPFWThreadExitStats; tmm_modules[TMM_RECEIVEIPFW].ThreadDeinit = ReceiveIPFWThreadDeinit; tmm_modules[TMM_RECEIVEIPFW].cap_flags = SC_CAP_NET_ADMIN | SC_CAP_NET_RAW | diff --git a/src/source-mpipe.c b/src/source-mpipe.c index 9fdebf65a0..fa9d14ce38 100644 --- a/src/source-mpipe.c +++ b/src/source-mpipe.c @@ -173,6 +173,7 @@ void TmModuleReceiveMpipeRegister (void) tmm_modules[TMM_RECEIVEMPIPE].ThreadInit = ReceiveMpipeThreadInit; tmm_modules[TMM_RECEIVEMPIPE].Func = NULL; tmm_modules[TMM_RECEIVEMPIPE].PktAcqLoop = ReceiveMpipeLoop; + tmm_modules[TMM_RECEIVEMPIPE].PktAcqBreakLoop = NULL; tmm_modules[TMM_RECEIVEMPIPE].ThreadExitPrintStats = ReceiveMpipeThreadExitStats; tmm_modules[TMM_RECEIVEMPIPE].ThreadDeinit = NULL; tmm_modules[TMM_RECEIVEMPIPE].RegisterTests = NULL; diff --git a/src/source-napatech.c b/src/source-napatech.c index 27432314e8..5566e40227 100644 --- a/src/source-napatech.c +++ b/src/source-napatech.c @@ -110,6 +110,7 @@ void TmModuleNapatechStreamRegister(void) tmm_modules[TMM_RECEIVENAPATECH].ThreadInit = NapatechStreamThreadInit; tmm_modules[TMM_RECEIVENAPATECH].Func = NULL; tmm_modules[TMM_RECEIVENAPATECH].PktAcqLoop = NapatechStreamLoop; + tmm_modules[TMM_RECEIVENAPATECH].PktAcqBreakLoop = NULL; tmm_modules[TMM_RECEIVENAPATECH].ThreadExitPrintStats = NapatechStreamThreadExitStats; tmm_modules[TMM_RECEIVENAPATECH].ThreadDeinit = NapatechStreamThreadDeinit; tmm_modules[TMM_RECEIVENAPATECH].RegisterTests = NULL; diff --git a/src/source-netmap.c b/src/source-netmap.c index 73930118c1..061635b647 100644 --- a/src/source-netmap.c +++ b/src/source-netmap.c @@ -1069,6 +1069,7 @@ void TmModuleReceiveNetmapRegister(void) tmm_modules[TMM_RECEIVENETMAP].ThreadInit = ReceiveNetmapThreadInit; tmm_modules[TMM_RECEIVENETMAP].Func = NULL; tmm_modules[TMM_RECEIVENETMAP].PktAcqLoop = ReceiveNetmapLoop; + tmm_modules[TMM_RECEIVENETMAP].PktAcqBreakLoop = NULL; tmm_modules[TMM_RECEIVENETMAP].ThreadExitPrintStats = ReceiveNetmapThreadExitStats; tmm_modules[TMM_RECEIVENETMAP].ThreadDeinit = ReceiveNetmapThreadDeinit; tmm_modules[TMM_RECEIVENETMAP].RegisterTests = NULL; diff --git a/src/source-nflog.c b/src/source-nflog.c index 7722244ffe..858ad76c79 100644 --- a/src/source-nflog.c +++ b/src/source-nflog.c @@ -117,6 +117,7 @@ void TmModuleReceiveNFLOGRegister (void) tmm_modules[TMM_RECEIVENFLOG].ThreadInit = ReceiveNFLOGThreadInit; tmm_modules[TMM_RECEIVENFLOG].Func = NULL; tmm_modules[TMM_RECEIVENFLOG].PktAcqLoop = ReceiveNFLOGLoop; + tmm_modules[TMM_RECEIVENFLOG].PktAcqBreakLoop = NULL; tmm_modules[TMM_RECEIVENFLOG].ThreadExitPrintStats = ReceiveNFLOGThreadExitStats; tmm_modules[TMM_RECEIVENFLOG].ThreadDeinit = ReceiveNFLOGThreadDeinit; tmm_modules[TMM_RECEIVENFLOG].RegisterTests = NULL; diff --git a/src/source-nfq.c b/src/source-nfq.c index 34c3734f01..c8923f63d6 100644 --- a/src/source-nfq.c +++ b/src/source-nfq.c @@ -186,6 +186,7 @@ void TmModuleReceiveNFQRegister (void) tmm_modules[TMM_RECEIVENFQ].ThreadInit = ReceiveNFQThreadInit; tmm_modules[TMM_RECEIVENFQ].Func = NULL; tmm_modules[TMM_RECEIVENFQ].PktAcqLoop = ReceiveNFQLoop; + tmm_modules[TMM_RECEIVENFQ].PktAcqBreakLoop = NULL; tmm_modules[TMM_RECEIVENFQ].ThreadExitPrintStats = ReceiveNFQThreadExitStats; tmm_modules[TMM_RECEIVENFQ].ThreadDeinit = ReceiveNFQThreadDeinit; tmm_modules[TMM_RECEIVENFQ].RegisterTests = NULL; diff --git a/src/source-pcap-file.c b/src/source-pcap-file.c index 0b982fd3ab..5f970d64fb 100644 --- a/src/source-pcap-file.c +++ b/src/source-pcap-file.c @@ -114,6 +114,7 @@ void TmModuleReceivePcapFileRegister (void) tmm_modules[TMM_RECEIVEPCAPFILE].ThreadInit = ReceivePcapFileThreadInit; tmm_modules[TMM_RECEIVEPCAPFILE].Func = NULL; tmm_modules[TMM_RECEIVEPCAPFILE].PktAcqLoop = ReceivePcapFileLoop; + tmm_modules[TMM_RECEIVEPCAPFILE].PktAcqBreakLoop = NULL; tmm_modules[TMM_RECEIVEPCAPFILE].ThreadExitPrintStats = ReceivePcapFileThreadExitStats; tmm_modules[TMM_RECEIVEPCAPFILE].ThreadDeinit = ReceivePcapFileThreadDeinit; tmm_modules[TMM_RECEIVEPCAPFILE].RegisterTests = NULL; diff --git a/src/source-pcap.c b/src/source-pcap.c index 1f0c59bd61..7c7a53e8c9 100644 --- a/src/source-pcap.c +++ b/src/source-pcap.c @@ -128,6 +128,7 @@ void TmModuleReceivePcapRegister (void) tmm_modules[TMM_RECEIVEPCAP].ThreadInit = ReceivePcapThreadInit; tmm_modules[TMM_RECEIVEPCAP].Func = NULL; tmm_modules[TMM_RECEIVEPCAP].PktAcqLoop = ReceivePcapLoop; + tmm_modules[TMM_RECEIVEPCAP].PktAcqBreakLoop = NULL; tmm_modules[TMM_RECEIVEPCAP].ThreadExitPrintStats = ReceivePcapThreadExitStats; tmm_modules[TMM_RECEIVEPCAP].ThreadDeinit = NULL; tmm_modules[TMM_RECEIVEPCAP].RegisterTests = NULL; diff --git a/src/source-pfring.c b/src/source-pfring.c index 527086f564..e1a811abe1 100644 --- a/src/source-pfring.c +++ b/src/source-pfring.c @@ -62,6 +62,7 @@ #endif /* __SC_CUDA_SUPPORT__ */ TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot); +TmEcode PfringBreakLoop(ThreadVars *tv, void *data); TmEcode ReceivePfringThreadInit(ThreadVars *, void *, void **); void ReceivePfringThreadExitStats(ThreadVars *, void *); TmEcode ReceivePfringThreadDeinit(ThreadVars *, void *); @@ -175,6 +176,7 @@ void TmModuleReceivePfringRegister (void) tmm_modules[TMM_RECEIVEPFRING].ThreadInit = ReceivePfringThreadInit; tmm_modules[TMM_RECEIVEPFRING].Func = NULL; tmm_modules[TMM_RECEIVEPFRING].PktAcqLoop = ReceivePfringLoop; + tmm_modules[TMM_RECEIVEPFRING].PktAcqBreakLoop = PfringBreakLoop; tmm_modules[TMM_RECEIVEPFRING].ThreadExitPrintStats = ReceivePfringThreadExitStats; tmm_modules[TMM_RECEIVEPFRING].ThreadDeinit = ReceivePfringThreadDeinit; tmm_modules[TMM_RECEIVEPFRING].RegisterTests = NULL; @@ -379,6 +381,31 @@ TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot) return TM_ECODE_OK; } +/** + * \brief Stop function for ReceivePfringLoop. + * + * This function forces ReceivePfringLoop to stop the + * execution, exiting the packet capture loop. + * + * \param tv pointer to ThreadVars + * \param data pointer that gets cast into PfringThreadVars for ptv + * \retval TM_ECODE_OK on success + * \retval TM_ECODE_FAILED on failure + */ +TmEcode PfringBreakLoop(ThreadVars *tv, void *data) +{ + PfringThreadVars *ptv = (PfringThreadVars *)data; + + /* Safety check */ + if (ptv->pd == NULL) { + return TM_ECODE_FAILED; + } + + pfring_breakloop(ptv->pd); + + return TM_ECODE_OK; +} + /** * \brief Init function for RecievePfring. * diff --git a/src/tm-modules.h b/src/tm-modules.h index c9d4e1f56e..3486ebf04a 100644 --- a/src/tm-modules.h +++ b/src/tm-modules.h @@ -49,6 +49,9 @@ typedef struct TmModule_ { TmEcode (*PktAcqLoop)(ThreadVars *, void *, void *); + /** terminates the capture loop in PktAcqLoop */ + TmEcode (*PktAcqBreakLoop)(ThreadVars *, void *); + TmEcode (*Management)(ThreadVars *, void *); /** global Init/DeInit */ diff --git a/src/tm-threads.c b/src/tm-threads.c index 2b26404fba..f0990f1343 100644 --- a/src/tm-threads.c +++ b/src/tm-threads.c @@ -1438,10 +1438,11 @@ again: * with all receive threads */ while (tv) { int disable = 0; + TmModule *tm = NULL; /* obtain the slots for this TV */ TmSlot *slots = tv->tm_slots; while (slots != NULL) { - TmModule *tm = TmModuleGetById(slots->tm_id); + tm = TmModuleGetById(slots->tm_id); if (tm->flags & TM_FLAG_RECEIVE_TM) { disable = 1; @@ -1470,6 +1471,9 @@ again: } /* we found a receive TV. Send it a KILL_PKTACQ signal. */ + if (tm && tm->PktAcqBreakLoop != NULL) { + tm->PktAcqBreakLoop(tv, SC_ATOMIC_GET(slots->slot_data)); + } TmThreadsSetFlag(tv, THV_KILL_PKTACQ); if (tv->inq != NULL) {