suricata
source-dpdk.c
Go to the documentation of this file.
1 /* Copyright (C) 2021 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  * \defgroup dpdk DPDK running mode
20  *
21  * @{
22  */
23 
24 /**
25  * \file
26  *
27  * \author Lukas Sismis <lukas.sismis@gmail.com>
28  *
29  * DPDK capture interface
30  *
31  */
32 
33 #include "suricata-common.h"
34 #include "runmodes.h"
35 #include "source-dpdk.h"
36 #include "suricata.h"
37 #include "threads.h"
38 #include "threadvars.h"
39 #include "tm-threads.h"
40 #include "tmqh-packetpool.h"
41 #include "util-privs.h"
42 
43 #ifndef HAVE_DPDK
44 
45 TmEcode NoDPDKSupportExit(ThreadVars *, const void *, void **);
46 
48 {
49  tmm_modules[TMM_RECEIVEDPDK].name = "ReceiveDPDK";
56 }
57 
58 /**
59  * \brief Registration Function for DecodeDPDK.
60  */
62 {
63  tmm_modules[TMM_DECODEDPDK].name = "DecodeDPDK";
70 }
71 
72 /**
73  * \brief this function prints an error message and exits.
74  */
75 TmEcode NoDPDKSupportExit(ThreadVars *tv, const void *initdata, void **data)
76 {
78  "Error creating thread %s: you do not have "
79  "support for DPDK enabled, on Linux host please recompile "
80  "with --enable-dpdk",
81  tv->name);
82 }
83 
84 #else /* We have DPDK support */
85 
86 #include "util-dpdk.h"
87 #include "util-dpdk-i40e.h"
88 #include <numa.h>
89 
90 #define BURST_SIZE 32
91 
92 /**
93  * \brief Structure to hold thread specific variables.
94  */
95 typedef struct DPDKThreadVars_ {
96  /* counters */
97  uint64_t pkts;
98  ThreadVars *tv;
99  TmSlot *slot;
100  LiveDevice *livedev;
101  ChecksumValidationMode checksum_mode;
102  /* references to packet and drop counters */
103  uint16_t capture_dpdk_packets;
104  uint16_t capture_dpdk_rx_errs;
105  uint16_t capture_dpdk_imissed;
106  uint16_t capture_dpdk_rx_no_mbufs;
107  uint16_t capture_dpdk_ierrors;
108  uint16_t capture_dpdk_tx_errs;
109  unsigned int flags;
110  int threads;
111  /* for IPS */
112  DpdkCopyModeEnum copy_mode;
113  uint16_t out_port_id;
114  /* Entry in the peers_list */
115 
116  uint64_t bytes;
117  uint64_t accepted;
118  uint64_t dropped;
119  uint16_t port_id;
120  uint16_t queue_id;
121  struct rte_mempool *pkt_mempool;
122  struct rte_mbuf *received_mbufs[BURST_SIZE];
123  struct timeval machine_start_time;
124 } DPDKThreadVars;
125 
126 static TmEcode ReceiveDPDKThreadInit(ThreadVars *, const void *, void **);
127 static void ReceiveDPDKThreadExitStats(ThreadVars *, void *);
128 static TmEcode ReceiveDPDKThreadDeinit(ThreadVars *, void *);
129 static TmEcode ReceiveDPDKLoop(ThreadVars *tv, void *data, void *slot);
130 
131 static TmEcode DecodeDPDKThreadInit(ThreadVars *, const void *, void **);
132 static TmEcode DecodeDPDKThreadDeinit(ThreadVars *tv, void *data);
133 static TmEcode DecodeDPDK(ThreadVars *, Packet *, void *);
134 
135 static uint64_t CyclesToMicroseconds(uint64_t cycles);
136 static uint64_t CyclesToSeconds(uint64_t cycles);
137 static void DPDKFreeMbufArray(struct rte_mbuf **mbuf_array, uint16_t mbuf_cnt, uint16_t offset);
138 static uint64_t DPDKGetSeconds(void);
139 
140 static void DPDKFreeMbufArray(struct rte_mbuf **mbuf_array, uint16_t mbuf_cnt, uint16_t offset)
141 {
142  for (int i = offset; i < mbuf_cnt; i++) {
143  rte_pktmbuf_free(mbuf_array[i]);
144  }
145 }
146 
147 static uint64_t CyclesToMicroseconds(const uint64_t cycles)
148 {
149  const uint64_t ticks_per_us = rte_get_tsc_hz() / 1000000;
150  return cycles / ticks_per_us;
151 }
152 
153 static uint64_t CyclesToSeconds(const uint64_t cycles)
154 {
155  const uint64_t ticks_per_s = rte_get_tsc_hz();
156  return cycles / ticks_per_s;
157 }
158 
159 static void CyclesAddToTimeval(
160  const uint64_t cycles, struct timeval *orig_tv, struct timeval *new_tv)
161 {
162  uint64_t usec = CyclesToMicroseconds(cycles) + orig_tv->tv_usec;
163  new_tv->tv_sec = orig_tv->tv_sec + usec / 1000000;
164  new_tv->tv_usec = (usec % 1000000);
165 }
166 
167 static void DPDKSetTimevalOfMachineStart(struct timeval *tv)
168 {
169  gettimeofday(tv, NULL);
170  tv->tv_sec -= DPDKGetSeconds();
171 }
172 
173 /**
174  * Initializes real_tv to the correct real time. Adds TSC counter value to the timeval of
175  * the machine start
176  * @param machine_start_tv - timestamp when the machine was started
177  * @param real_tv
178  */
179 static void DPDKSetTimevalReal(struct timeval *machine_start_tv, struct timeval *real_tv)
180 {
181  CyclesAddToTimeval(rte_get_tsc_cycles(), machine_start_tv, real_tv);
182 }
183 
184 /* get number of seconds from the reset of TSC counter (typically from the machine start) */
185 static uint64_t DPDKGetSeconds()
186 {
187  return CyclesToSeconds(rte_get_tsc_cycles());
188 }
189 
190 static void DevicePostStartPMDSpecificActions(DPDKThreadVars *ptv, const char *driver_name)
191 {
192  // The PMD Driver i40e has a special way to set the RSS, it can be set via rte_flow rules
193  // and only after the start of the port
194  if (strcmp(driver_name, "net_i40e") == 0)
195  i40eDeviceSetRSS(ptv->port_id, ptv->threads);
196 }
197 
198 static void DevicePreStopPMDSpecificActions(DPDKThreadVars *ptv, const char *driver_name)
199 {
200  int retval;
201 
202  if (strcmp(driver_name, "net_i40e") == 0) {
203  // Flush the RSS rules that have been inserted in the post start section
204  struct rte_flow_error flush_error = { 0 };
205  retval = rte_flow_flush(ptv->port_id, &flush_error);
206  if (retval != 0) {
207  SCLogError(SC_ERR_DPDK_CONF, "Unable to flush rte_flow rules: %s Flush error msg: %s",
208  rte_strerror(-retval), flush_error.message);
209  }
210  }
211 }
212 
213 /**
214  * Attempts to retrieve NUMA node id on which the caller runs
215  * @return NUMA id on success, -1 otherwise
216  */
217 static int GetNumaNode(void)
218 {
219  int cpu = 0;
220  int node = -1;
221 
222 #if defined(__linux__)
223  cpu = sched_getcpu();
224  node = numa_node_of_cpu(cpu);
225 #else
226  SCLogWarning(SC_ERR_TM_THREADS_ERROR, "NUMA node retrieval is not supported on this OS.");
227 #endif
228 
229  return node;
230 }
231 
232 /**
233  * \brief Registration Function for ReceiveDPDK.
234  * \todo Unit tests are needed for this module.
235  */
237 {
238  tmm_modules[TMM_RECEIVEDPDK].name = "ReceiveDPDK";
239  tmm_modules[TMM_RECEIVEDPDK].ThreadInit = ReceiveDPDKThreadInit;
241  tmm_modules[TMM_RECEIVEDPDK].PktAcqLoop = ReceiveDPDKLoop;
243  tmm_modules[TMM_RECEIVEDPDK].ThreadExitPrintStats = ReceiveDPDKThreadExitStats;
244  tmm_modules[TMM_RECEIVEDPDK].ThreadDeinit = ReceiveDPDKThreadDeinit;
247 }
248 
249 /**
250  * \brief Registration Function for DecodeDPDK.
251  * \todo Unit tests are needed for this module.
252  */
254 {
255  tmm_modules[TMM_DECODEDPDK].name = "DecodeDPDK";
256  tmm_modules[TMM_DECODEDPDK].ThreadInit = DecodeDPDKThreadInit;
257  tmm_modules[TMM_DECODEDPDK].Func = DecodeDPDK;
259  tmm_modules[TMM_DECODEDPDK].ThreadDeinit = DecodeDPDKThreadDeinit;
262 }
263 
264 static inline void DPDKDumpCounters(DPDKThreadVars *ptv)
265 {
266  struct rte_eth_stats eth_stats;
267  int retval = rte_eth_stats_get(ptv->port_id, &eth_stats);
268  if (unlikely(retval != 0)) {
269  SCLogError(SC_ERR_STAT, "Failed to get stats for port id %d: %s", ptv->port_id,
270  rte_strerror(-retval));
271  return;
272  }
273 
274  /* Some NICs (e.g. Intel) do not support queue statistics and the drops can be fetched only on
275  * the port level. Therefore setting it to the first worker to have at least continuous update
276  * on the dropped packets. */
277  if (ptv->queue_id == 0) {
278  StatsSetUI64(ptv->tv, ptv->capture_dpdk_packets,
279  ptv->pkts + eth_stats.imissed + eth_stats.ierrors + eth_stats.rx_nombuf);
280  SC_ATOMIC_SET(ptv->livedev->pkts,
281  eth_stats.ipackets + eth_stats.imissed + eth_stats.ierrors + eth_stats.rx_nombuf);
282  StatsSetUI64(ptv->tv, ptv->capture_dpdk_rx_errs,
283  eth_stats.imissed + eth_stats.ierrors + eth_stats.rx_nombuf);
284  StatsSetUI64(ptv->tv, ptv->capture_dpdk_imissed, eth_stats.imissed);
285  StatsSetUI64(ptv->tv, ptv->capture_dpdk_rx_no_mbufs, eth_stats.rx_nombuf);
286  StatsSetUI64(ptv->tv, ptv->capture_dpdk_ierrors, eth_stats.ierrors);
287  StatsSetUI64(ptv->tv, ptv->capture_dpdk_tx_errs, eth_stats.oerrors);
289  ptv->livedev->drop, eth_stats.imissed + eth_stats.ierrors + eth_stats.rx_nombuf);
290  } else {
291  StatsSetUI64(ptv->tv, ptv->capture_dpdk_packets, ptv->pkts);
292  }
293 }
294 
295 static void DPDKReleasePacket(Packet *p)
296 {
297  int retval;
298  /* Need to be in copy mode and need to detect early release
299  where Ethernet header could not be set (and pseudo packet)
300  When enabling promiscuous mode on Intel cards, 2 ICMPv6 packets are generated.
301  These get into the infinite cycle between the NIC and the switch in some cases */
302  if ((p->dpdk_v.copy_mode == DPDK_COPY_MODE_TAP ||
303  (p->dpdk_v.copy_mode == DPDK_COPY_MODE_IPS && !PacketTestAction(p, ACTION_DROP)))
304 #if defined(RTE_LIBRTE_I40E_PMD) || defined(RTE_LIBRTE_IXGBE_PMD) || defined(RTE_LIBRTE_ICE_PMD)
305  && !(PKT_IS_ICMPV6(p) && p->icmpv6h->type == 143)
306 #endif
307  ) {
309  retval =
310  rte_eth_tx_burst(p->dpdk_v.out_port_id, p->dpdk_v.out_queue_id, &p->dpdk_v.mbuf, 1);
311  // rte_eth_tx_burst can return only 0 (failure) or 1 (success) because we are only
312  // transmitting burst of size 1 and the function rte_eth_tx_burst returns number of
313  // successfully sent packets.
314  if (unlikely(retval < 1)) {
315  // sometimes a repeated transmit can help to send out the packet
316  rte_delay_us(DPDK_BURST_TX_WAIT_US);
317  retval = rte_eth_tx_burst(
318  p->dpdk_v.out_port_id, p->dpdk_v.out_queue_id, &p->dpdk_v.mbuf, 1);
319  if (unlikely(retval < 1)) {
320  SCLogDebug("Unable to transmit the packet on port %u queue %u",
321  p->dpdk_v.out_port_id, p->dpdk_v.out_queue_id);
322  rte_pktmbuf_free(p->dpdk_v.mbuf);
323  p->dpdk_v.mbuf = NULL;
324  }
325  }
326  } else {
327  rte_pktmbuf_free(p->dpdk_v.mbuf);
328  p->dpdk_v.mbuf = NULL;
329  }
330 
332 }
333 
334 /**
335  * \brief Main DPDK reading Loop function
336  */
337 static TmEcode ReceiveDPDKLoop(ThreadVars *tv, void *data, void *slot)
338 {
339  SCEnter();
340  Packet *p;
341  uint16_t nb_rx;
342  time_t last_dump = 0;
343  time_t current_time;
344 
345  DPDKThreadVars *ptv = (DPDKThreadVars *)data;
346  TmSlot *s = (TmSlot *)slot;
347 
348  ptv->slot = s->slot_next;
349 
350  PacketPoolWait();
351  while (1) {
352  if (unlikely(suricata_ctl_flags != 0)) {
353  SCLogDebug("Stopping Suricata!");
354  DPDKDumpCounters(ptv);
355  break;
356  }
357 
358  nb_rx = rte_eth_rx_burst(ptv->port_id, ptv->queue_id, ptv->received_mbufs, BURST_SIZE);
359  if (unlikely(nb_rx == 0)) {
360  continue;
361  }
362 
363  ptv->pkts += (uint64_t)nb_rx;
364  for (uint16_t i = 0; i < nb_rx; i++) {
366  if (unlikely(p == NULL)) {
367  continue;
368  }
371  if (ptv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) {
373  }
374 
375  DPDKSetTimevalReal(&ptv->machine_start_time, &p->ts);
376  p->dpdk_v.mbuf = ptv->received_mbufs[i];
377  p->ReleasePacket = DPDKReleasePacket;
378  p->dpdk_v.copy_mode = ptv->copy_mode;
379  p->dpdk_v.out_port_id = ptv->out_port_id;
380  p->dpdk_v.out_queue_id = ptv->queue_id;
381 
382  PacketSetData(p, rte_pktmbuf_mtod(p->dpdk_v.mbuf, uint8_t *),
383  rte_pktmbuf_pkt_len(p->dpdk_v.mbuf));
384  if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
385  TmqhOutputPacketpool(ptv->tv, p);
386  DPDKFreeMbufArray(ptv->received_mbufs, nb_rx - i - 1, i + 1);
387  SCReturnInt(EXIT_FAILURE);
388  }
389  }
390 
391  /* Trigger one dump of stats every second */
392  current_time = DPDKGetSeconds();
393  if (current_time != last_dump) {
394  DPDKDumpCounters(ptv);
395  last_dump = current_time;
396  }
398  }
399 
401 }
402 
403 /**
404  * \brief Init function for ReceiveDPDK.
405  *
406  * \param tv pointer to ThreadVars
407  * \param initdata pointer to the interface passed from the user
408  * \param data pointer gets populated with DPDKThreadVars
409  *
410  */
411 static TmEcode ReceiveDPDKThreadInit(ThreadVars *tv, const void *initdata, void **data)
412 {
413  SCEnter();
414  int retval, thread_numa;
415  DPDKThreadVars *ptv = NULL;
416  DPDKIfaceConfig *dpdk_config = (DPDKIfaceConfig *)initdata;
417 
418  if (initdata == NULL) {
419  SCLogError(SC_ERR_INVALID_ARGUMENT, "DPDK configuration is NULL in thread initialization");
420  goto fail;
421  }
422 
423  ptv = SCCalloc(1, sizeof(DPDKThreadVars));
424  if (unlikely(ptv == NULL)) {
425  SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate memory");
426  goto fail;
427  }
428 
429  ptv->tv = tv;
430  ptv->pkts = 0;
431  ptv->bytes = 0;
432  ptv->livedev = LiveGetDevice(dpdk_config->iface);
433  DPDKSetTimevalOfMachineStart(&ptv->machine_start_time);
434 
435  ptv->capture_dpdk_packets = StatsRegisterCounter("capture.packets", ptv->tv);
436  ptv->capture_dpdk_rx_errs = StatsRegisterCounter("capture.rx_errors", ptv->tv);
437  ptv->capture_dpdk_tx_errs = StatsRegisterCounter("capture.tx_errors", ptv->tv);
438  ptv->capture_dpdk_imissed = StatsRegisterCounter("capture.dpdk.imissed", ptv->tv);
439  ptv->capture_dpdk_rx_no_mbufs = StatsRegisterCounter("capture.dpdk.no_mbufs", ptv->tv);
440  ptv->capture_dpdk_ierrors = StatsRegisterCounter("capture.dpdk.ierrors", ptv->tv);
441 
442  ptv->copy_mode = dpdk_config->copy_mode;
443  ptv->checksum_mode = dpdk_config->checksum_mode;
444 
445  ptv->threads = dpdk_config->threads;
446  ptv->port_id = dpdk_config->port_id;
447  ptv->out_port_id = dpdk_config->out_port_id;
448  uint16_t queue_id = SC_ATOMIC_ADD(dpdk_config->queue_id, 1);
449  ptv->queue_id = queue_id;
450  // pass the pointer to the mempool and then forget about it. Mempool is freed in thread deinit.
451  ptv->pkt_mempool = dpdk_config->pkt_mempool;
452  dpdk_config->pkt_mempool = NULL;
453 
454  // the last thread starts the device
455  if (queue_id == dpdk_config->threads - 1) {
456  retval = rte_eth_dev_start(ptv->port_id);
457  if (retval < 0) {
458  SCLogError(SC_ERR_DPDK_INIT, "Error (%s) during device startup of %s",
459  rte_strerror(-retval), dpdk_config->iface);
460  goto fail;
461  }
462 
463  struct rte_eth_dev_info dev_info;
464  retval = rte_eth_dev_info_get(ptv->port_id, &dev_info);
465  if (retval != 0) {
466  SCLogError(SC_ERR_DPDK_INIT, "Error (%s) when getting device info of %s",
467  rte_strerror(-retval), dpdk_config->iface);
468  goto fail;
469  }
470 
471  // some PMDs requires additional actions only after the device has started
472  DevicePostStartPMDSpecificActions(ptv, dev_info.driver_name);
473  }
474 
475  thread_numa = GetNumaNode();
476  if (thread_numa >= 0 && thread_numa != rte_eth_dev_socket_id(ptv->port_id)) {
478  "NIC on NUMA %d but thread on NUMA %d. Decreased performance expected",
479  rte_eth_dev_socket_id(ptv->port_id), thread_numa);
480  }
481 
482  *data = (void *)ptv;
483  dpdk_config->DerefFunc(dpdk_config);
485 
486 fail:
487  if (dpdk_config != NULL)
488  dpdk_config->DerefFunc(dpdk_config);
489  if (ptv != NULL)
490  SCFree(ptv);
492 }
493 
494 /**
495  * \brief This function prints stats to the screen at exit.
496  * \param tv pointer to ThreadVars
497  * \param data pointer that gets cast into DPDKThreadVars for ptv
498  */
499 static void ReceiveDPDKThreadExitStats(ThreadVars *tv, void *data)
500 {
501  SCEnter();
502  int retval;
503  DPDKThreadVars *ptv = (DPDKThreadVars *)data;
504 
505  if (ptv->queue_id == 0) {
506  struct rte_eth_stats eth_stats;
507  char port_name[RTE_ETH_NAME_MAX_LEN];
508 
509  retval = rte_eth_dev_get_name_by_port(ptv->port_id, port_name);
510  if (unlikely(retval != 0)) {
511  SCLogError(SC_ERR_STAT, "Failed to convert port id %d to the interface name: %s",
512  ptv->port_id, strerror(-retval));
513  SCReturn;
514  }
515  retval = rte_eth_stats_get(ptv->port_id, &eth_stats);
516  if (unlikely(retval != 0)) {
517  SCLogError(SC_ERR_STAT, "Failed to get stats for interface %s: %s", port_name,
518  strerror(-retval));
519  SCReturn;
520  }
521  SCLogPerf("Total RX stats of %s: packets %" PRIu64 " bytes: %" PRIu64 " missed: %" PRIu64
522  " errors: %" PRIu64 " nombufs: %" PRIu64,
523  port_name, eth_stats.ipackets, eth_stats.ibytes, eth_stats.imissed,
524  eth_stats.ierrors, eth_stats.rx_nombuf);
525  if (ptv->copy_mode == DPDK_COPY_MODE_TAP || ptv->copy_mode == DPDK_COPY_MODE_IPS)
526  SCLogPerf("Total TX stats of %s: packets %" PRIu64 " bytes: %" PRIu64
527  " errors: %" PRIu64,
528  port_name, eth_stats.opackets, eth_stats.obytes, eth_stats.oerrors);
529  }
530 
531  DPDKDumpCounters(ptv);
532  SCLogPerf("(%s) received packets %" PRIu64, tv->name, ptv->pkts);
533 }
534 
535 /**
536  * \brief DeInit function closes dpdk at exit.
537  * \param tv pointer to ThreadVars
538  * \param data pointer that gets cast into DPDKThreadVars for ptv
539  */
540 static TmEcode ReceiveDPDKThreadDeinit(ThreadVars *tv, void *data)
541 {
542  SCEnter();
543  DPDKThreadVars *ptv = (DPDKThreadVars *)data;
544 
545  int retval;
546  if (ptv->queue_id == 0) {
547  struct rte_eth_dev_info dev_info;
548  char iface[RTE_ETH_NAME_MAX_LEN];
549  retval = rte_eth_dev_get_name_by_port(ptv->port_id, iface);
550  if (retval != 0) {
551  SCLogError(SC_ERR_DPDK_INIT, "Error (err=%d) when getting device name (port %d)",
552  retval, ptv->port_id);
554  }
555  retval = rte_eth_dev_info_get(ptv->port_id, &dev_info);
556  if (retval != 0) {
557  SCLogError(SC_ERR_DPDK_INIT, "Error (err=%d) during getting device info (port %s)",
558  retval, iface);
560  }
561 
562  DevicePreStopPMDSpecificActions(ptv, dev_info.driver_name);
563  }
564 
565  rte_eth_dev_stop(ptv->port_id);
566  if (ptv->copy_mode == DPDK_COPY_MODE_TAP || ptv->copy_mode == DPDK_COPY_MODE_IPS) {
567  rte_eth_dev_stop(ptv->out_port_id);
568  }
569 
570  if (ptv->queue_id == 0 && ptv->pkt_mempool != NULL) {
571  rte_mempool_free(ptv->pkt_mempool);
572  ptv->pkt_mempool = NULL;
573  }
574 
575  SCFree(ptv);
577 }
578 
579 /**
580  * \brief This function passes off to link type decoders.
581  *
582  * DecodeDPDK decodes packets from DPDK and passes
583  * them off to the proper link type decoder.
584  *
585  * \param t pointer to ThreadVars
586  * \param p pointer to the current packet
587  * \param data pointer that gets cast into DPDKThreadVars for ptv
588  */
589 static TmEcode DecodeDPDK(ThreadVars *tv, Packet *p, void *data)
590 {
591  SCEnter();
593 
595 
596  /* update counters */
598 
599  /* If suri has set vlan during reading, we increase vlan counter */
600  if (p->vlan_idx) {
602  }
603 
604  /* call the decoder */
605  DecodeLinkLayer(tv, dtv, p->datalink, p, GET_PKT_DATA(p), GET_PKT_LEN(p));
606 
608 
610 }
611 
612 static TmEcode DecodeDPDKThreadInit(ThreadVars *tv, const void *initdata, void **data)
613 {
614  SCEnter();
615  DecodeThreadVars *dtv = NULL;
616 
618 
619  if (dtv == NULL)
621 
623 
624  *data = (void *)dtv;
625 
627 }
628 
629 static TmEcode DecodeDPDKThreadDeinit(ThreadVars *tv, void *data)
630 {
631  SCEnter();
632  if (data != NULL)
633  DecodeThreadVarsFree(tv, data);
635 }
636 
637 #endif /* HAVE_DPDK */
638 /* eof */
639 /**
640  * @}
641  */
TmModule_::cap_flags
uint8_t cap_flags
Definition: tm-modules.h:67
SC_ERR_DPDK_INIT
@ SC_ERR_DPDK_INIT
Definition: util-error.h:373
tm-threads.h
TMM_RECEIVEDPDK
@ TMM_RECEIVEDPDK
Definition: tm-threads-common.h:56
SC_ERR_TM_THREADS_ERROR
@ SC_ERR_TM_THREADS_ERROR
Definition: util-error.h:166
ICMPV6Hdr_::type
uint8_t type
Definition: decode-icmpv6.h:146
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:169
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
ThreadVars_::name
char name[16]
Definition: threadvars.h:65
PacketFreeOrRelease
void PacketFreeOrRelease(Packet *p)
Return a packet to where it was allocated.
Definition: decode.c:194
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1224
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SC_WARN_DPDK_CONF
@ SC_WARN_DPDK_CONF
Definition: util-error.h:377
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:387
DPDK_COPY_MODE_IPS
@ DPDK_COPY_MODE_IPS
Definition: source-dpdk.h:30
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
TMM_DECODEDPDK
@ TMM_DECODEDPDK
Definition: tm-threads-common.h:57
Packet_::flags
uint32_t flags
Definition: decode.h:462
DpdkCopyModeEnum
DpdkCopyModeEnum
Definition: source-dpdk.h:30
threads.h
Packet_::vlan_idx
uint8_t vlan_idx
Definition: decode.h:455
LiveDevice_
Definition: util-device.h:40
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:333
StatsSetUI64
void StatsSetUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Sets a value of type double to the local counter.
Definition: counters.c:191
NoDPDKSupportExit
TmEcode NoDPDKSupportExit(ThreadVars *, const void *, void **)
this function prints an error message and exits.
Definition: source-dpdk.c:75
util-privs.h
StatsSyncCountersIfSignalled
#define StatsSyncCountersIfSignalled(tv)
Definition: counters.h:137
CHECKSUM_VALIDATION_DISABLE
@ CHECKSUM_VALIDATION_DISABLE
Definition: decode.h:43
PacketDecodeFinalize
void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Finalize decoding of a packet.
Definition: decode.c:147
DPDKIfaceConfig_
Definition: source-dpdk.h:41
TmqhOutputPacketpool
void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
Definition: tmqh-packetpool.c:375
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:83
tmqh-packetpool.h
TmModule_::PktAcqLoop
TmEcode(* PktAcqLoop)(ThreadVars *, void *, void *)
Definition: tm-modules.h:54
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:82
TmModule_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
Packet_::datalink
int datalink
Definition: decode.h:601
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1227
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:517
TmModuleReceiveDPDKRegister
void TmModuleReceiveDPDKRegister(void)
Definition: source-dpdk.c:47
PKT_SRC_WIRE
@ PKT_SRC_WIRE
Definition: decode.h:51
SC_ERR_DPDK_CONF
@ SC_ERR_DPDK_CONF
Definition: util-error.h:376
TmModule_::PktAcqBreakLoop
TmEcode(* PktAcqBreakLoop)(ThreadVars *, void *)
Definition: tm-modules.h:57
LiveGetDevice
LiveDevice * LiveGetDevice(const char *name)
Get a pointer to the device at idx.
Definition: util-device.c:279
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
GET_PKT_DATA
#define GET_PKT_DATA(p)
Definition: decode.h:236
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
TmModule_::Func
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition: tm-modules.h:52
SC_ERR_INVALID_ARGUMENT
@ SC_ERR_INVALID_ARGUMENT
Definition: util-error.h:43
PKT_IS_ICMPV6
#define PKT_IS_ICMPV6(p)
Definition: decode.h:267
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:281
PacketPoolWait
void PacketPoolWait(void)
Definition: tmqh-packetpool.c:84
SCReturn
#define SCReturn
Definition: util-debug.h:302
Packet_::icmpv6h
ICMPV6Hdr * icmpv6h
Definition: decode.h:557
Packet_
Definition: decode.h:427
TM_FLAG_DECODE_TM
#define TM_FLAG_DECODE_TM
Definition: tm-modules.h:32
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:33
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:235
TmSlot_
Definition: tm-threads.h:52
PKT_IGNORE_CHECKSUM
#define PKT_IGNORE_CHECKSUM
Definition: decode.h:1191
DPDK_BURST_TX_WAIT_US
#define DPDK_BURST_TX_WAIT_US
Definition: source-dpdk.h:32
TmEcode
TmEcode
Definition: tm-threads-common.h:81
TmModule_::name
const char * name
Definition: tm-modules.h:44
DecodeThreadVars_::counter_vlan
uint16_t counter_vlan
Definition: decode.h:685
runmodes.h
TM_FLAG_RECEIVE_TM
#define TM_FLAG_RECEIVE_TM
Definition: tm-modules.h:31
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:30
Packet_::ReleasePacket
void(* ReleasePacket)(struct Packet_ *)
Definition: decode.h:509
util-dpdk.h
flags
uint8_t flags
Definition: decode-gre.h:0
DecodeThreadVarsFree
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:694
source-dpdk.h
Packet_::ts
struct timeval ts
Definition: decode.h:470
ChecksumValidationMode
ChecksumValidationMode
Definition: decode.h:42
suricata-common.h
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
SCLogPerf
#define SCLogPerf(...)
Definition: util-debug.h:224
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
FatalError
#define FatalError(x,...)
Definition: util-debug.h:532
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
TmModule_::ThreadExitPrintStats
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:48
threadvars.h
SCLogWarning
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:244
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:654
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:675
PacketSetData
int PacketSetData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Set data for Packet and set length when zero copy is used.
Definition: decode.c:714
SC_ERR_STAT
@ SC_ERR_STAT
Definition: util-error.h:145
SC_ERR_MEM_ALLOC
@ SC_ERR_MEM_ALLOC
Definition: util-error.h:31
util-dpdk-i40e.h
suricata.h
SC_ERR_NO_DPDK
@ SC_ERR_NO_DPDK
Definition: util-error.h:372
TmSlot_::slot_next
struct TmSlot_ * slot_next
Definition: tm-threads.h:61
TmModuleDecodeDPDKRegister
void TmModuleDecodeDPDKRegister(void)
Registration Function for DecodeDPDK.
Definition: source-dpdk.c:61
StatsRegisterCounter
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:936
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
PacketGetFromQueueOrAlloc
Packet * PacketGetFromQueueOrAlloc(void)
Get a packet. We try to get a packet from the packetpool first, but if that is empty we alloc a packe...
Definition: decode.c:211
SC_CAP_NET_RAW
#define SC_CAP_NET_RAW
Definition: util-privs.h:32
TmModule_::flags
uint8_t flags
Definition: tm-modules.h:70
DPDK_COPY_MODE_TAP
@ DPDK_COPY_MODE_TAP
Definition: source-dpdk.h:30
DecodeUpdatePacketCounters
void DecodeUpdatePacketCounters(ThreadVars *tv, const DecodeThreadVars *dtv, const Packet *p)
Definition: decode.c:641
LINKTYPE_ETHERNET
#define LINKTYPE_ETHERNET
Definition: decode.h:1144
suricata_ctl_flags
volatile uint8_t suricata_ctl_flags
Definition: suricata.c:200