suricata
source-pfring.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2019 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 William Metcalf <william.metcalf@gmail.com>
22  * \author Eric Leblond <eric@regit.org>
23  *
24  * PF_RING packet acquisition support
25  *
26  * \todo remove requirement for setting cluster so old 3.x versions are supported
27  * \todo implement DNA support
28  * \todo Allow ring options such as snaplen etc, to be user configurable.
29  */
30 
31 #include "suricata-common.h"
32 #include "suricata.h"
33 #include "conf.h"
34 #include "decode.h"
35 #include "packet-queue.h"
36 #include "threads.h"
37 #include "threadvars.h"
38 #include "tm-queuehandlers.h"
39 #include "tm-threads.h"
40 #include "source-pfring.h"
41 #include "util-debug.h"
42 #include "util-checksum.h"
43 #include "util-privs.h"
44 #include "util-datalink.h"
45 #include "util-device.h"
46 #include "util-host-info.h"
47 #include "runmodes.h"
48 #include "util-profiling.h"
49 
50 TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot);
51 TmEcode PfringBreakLoop(ThreadVars *tv, void *data);
52 TmEcode ReceivePfringThreadInit(ThreadVars *, const void *, void **);
55 
56 TmEcode DecodePfringThreadInit(ThreadVars *, const void *, void **);
59 
60 extern uint16_t max_pending_packets;
61 
62 #ifndef HAVE_PFRING
63 
64 /*Handle cases where we don't have PF_RING support built-in*/
65 TmEcode NoPfringSupportExit(ThreadVars *, const void *, void **);
66 
68 {
69  tmm_modules[TMM_RECEIVEPFRING].name = "ReceivePfring";
70  tmm_modules[TMM_RECEIVEPFRING].ThreadInit = NoPfringSupportExit;
77 }
78 
80 {
81  tmm_modules[TMM_DECODEPFRING].name = "DecodePfring";
82  tmm_modules[TMM_DECODEPFRING].ThreadInit = NoPfringSupportExit;
88 }
89 
90 /**
91  * \brief this function prints an error message and exits.
92  * \param tv pointer to ThreadVars
93  * \param initdata pointer to the interface passed from the user
94  * \param data pointer gets populated with PfringThreadVars
95  */
96 TmEcode NoPfringSupportExit(ThreadVars *tv, const void *initdata, void **data)
97 {
98  SCLogError("Error creating thread %s: you do not have support for pfring "
99  "enabled please recompile with --enable-pfring",
100  tv->name);
101  exit(EXIT_FAILURE);
102 }
103 
104 #else /* implied we do have PF_RING support */
105 
106 #include <pfring.h>
107 
108 /** protect pfring_set_bpf_filter, as it is not thread safe */
109 static SCMutex pfring_bpf_set_filter_lock = SCMUTEX_INITIALIZER;
110 
111 /* XXX replace with user configurable options */
112 #define LIBPFRING_PROMISC 1
113 #define LIBPFRING_REENTRANT 0
114 #define LIBPFRING_WAIT_FOR_INCOMING 1
115 
116 /* PfringThreadVars flags */
117 #define PFRING_FLAGS_ZERO_COPY (1 << 0)
118 #define PFRING_FLAGS_BYPASS (1 << 1)
119 
120 /**
121  * \brief Structure to hold thread specific variables.
122  */
124 {
125  /* thread specific handle */
126  pfring *pd;
127 
128  /* counters */
129  uint64_t bytes;
130  uint64_t pkts;
131 
135 
136  uint32_t flags;
137 
140 
142 
143  /* threads count */
144  int threads;
145 
146  cluster_type ctype;
147 
148  uint8_t cluster_id;
149  char *interface;
151 
152  char *bpf_filter;
153 
155 
157 };
158 
159 /**
160  * \brief Registration Function for ReceivePfring.
161  * \todo Unit tests are needed for this module.
162  */
164 {
165  tmm_modules[TMM_RECEIVEPFRING].name = "ReceivePfring";
173 }
174 
175 /**
176  * \brief Registration Function for DecodePfring.
177  * \todo Unit tests are needed for this module.
178  */
180 {
181  tmm_modules[TMM_DECODEPFRING].name = "DecodePfring";
187 }
188 
189 static inline void PfringDumpCounters(PfringThreadVars *ptv)
190 {
191  pfring_stat pfring_s;
192  if (likely((pfring_stats(ptv->pd, &pfring_s) >= 0))) {
193  /* pfring counter is per socket and is not cleared after read.
194  * So to get the number of packet on the interface we can add
195  * the newly seen packets and drops for this thread and add it
196  * to the interface counter */
197  uint64_t th_pkts = StatsGetLocalCounterValue(ptv->tv, ptv->capture_kernel_packets);
198  uint64_t th_drops = StatsGetLocalCounterValue(ptv->tv, ptv->capture_kernel_drops);
199  SC_ATOMIC_ADD(ptv->livedev->pkts, pfring_s.recv - th_pkts);
200  SC_ATOMIC_ADD(ptv->livedev->drop, pfring_s.drop - th_drops);
201  StatsSetUI64(ptv->tv, ptv->capture_kernel_packets, pfring_s.recv);
202  StatsSetUI64(ptv->tv, ptv->capture_kernel_drops, pfring_s.drop);
203 
204 #ifdef HAVE_PF_RING_FLOW_OFFLOAD
205  if (ptv->flags & PFRING_FLAGS_BYPASS) {
206  uint64_t th_bypassed = StatsGetLocalCounterValue(ptv->tv, ptv->capture_bypassed);
207  SC_ATOMIC_ADD(ptv->livedev->bypassed, pfring_s.shunt - th_bypassed);
208  StatsSetUI64(ptv->tv, ptv->capture_bypassed, pfring_s.shunt);
209  }
210 #endif
211  }
212 }
213 
214 /**
215  * \brief Pfring Packet Process function.
216  *
217  * This function fills in our packet structure from libpfring.
218  * From here the packets are picked up by the DecodePfring thread.
219  *
220  * \param user pointer to PfringThreadVars
221  * \param h pointer to pfring packet header
222  * \param p pointer to the current packet
223  */
224 static inline void PfringProcessPacket(void *user, struct pfring_pkthdr *h, Packet *p)
225 {
226  PfringThreadVars *ptv = (PfringThreadVars *)user;
227 
228  ptv->bytes += h->caplen;
229  ptv->pkts++;
230  p->livedev = ptv->livedev;
231 
232  /* PF_RING may fail to set timestamp */
233  if (h->ts.tv_sec == 0) {
234  struct timeval tmp_ts;
235  gettimeofday(&tmp_ts, NULL);
236  h->ts = tmp_ts;
237  }
238 
239  p->ts = SCTIME_FROM_TIMEVAL(&h->ts);
240 
241  /* PF_RING all packets are marked as a link type of ethernet
242  * so that is what we do here. */
244 
245  /* In the past, we needed this vlan handling in cases
246  * where the vlan header was stripped from the raw packet.
247  * With modern (at least >= 6) versions of PF_RING, the
248  * 'copy_data_to_ring' function (kernel/pf_ring.c) makes
249  * sure that if the hardware stripped the vlan header,
250  * it is put back by PF_RING.
251  *
252  * PF_RING should put it back in all cases, but as a extra
253  * precaution keep the check here. If the vlan header is
254  * part of the raw packet, the vlan_offset will be set.
255  * So if it is not set, use the parsed info from PF_RING's
256  * extended header.
257  */
258  if (ptv->vlan_in_ext_header &&
259  h->extended_hdr.parsed_pkt.offset.vlan_offset == 0 &&
260  h->extended_hdr.parsed_pkt.vlan_id)
261  {
262  p->vlan_id[0] = h->extended_hdr.parsed_pkt.vlan_id & 0x0fff;
263  p->vlan_idx = 1;
264 
265  if (!ptv->vlan_hdr_warned) {
266  SCLogWarning("no VLAN header in the raw "
267  "packet. See ticket #2355.");
268  ptv->vlan_hdr_warned = true;
269  }
270  }
271 
272  switch (ptv->checksum_mode) {
274  if (h->extended_hdr.rx_direction == 0) {
276  }
277  break;
280  break;
282  if (ChecksumAutoModeCheck(ptv->pkts,
283  SC_ATOMIC_GET(ptv->livedev->pkts),
284  SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
287  }
288  break;
289  default:
290  break;
291  }
292 
293  SET_PKT_LEN(p, h->caplen);
294 }
295 
296 #ifdef HAVE_PF_RING_FLOW_OFFLOAD
297 /**
298  * \brief Pfring bypass callback function
299  *
300  * \param p a Packet to use information from to trigger bypass
301  * \return 1 if bypass is successful, 0 if not
302  */
303 static int PfringBypassCallback(Packet *p)
304 {
305  hw_filtering_rule r;
306 
307  /* Only bypass TCP and UDP */
308  if (!(PKT_IS_TCP(p) || PKT_IS_UDP(p))) {
309  return 0;
310  }
311 
312  /* Bypassing tunneled packets is currently not supported */
313  if (PacketIsTunnel(p)) {
314  return 0;
315  }
316 
317  r.rule_family_type = generic_flow_id_rule;
318  r.rule_family.flow_id_rule.action = flow_drop_rule;
319  r.rule_family.flow_id_rule.thread = 0;
320  r.rule_family.flow_id_rule.flow_id = p->pfring_v.flow_id;
321 
322  SCLogDebug("Bypass set for flow ID = %u", p->pfring_v.flow_id);
323 
324  if (pfring_add_hw_rule(p->pfring_v.ptv->pd, &r) < 0) {
325  return 0;
326  }
327 
328  return 1;
329 }
330 #endif
331 
332 /**
333  * \brief Receives packets from an interface via libpfring.
334  *
335  * This function receives packets from an interface and passes
336  * the packet on to the pfring callback function.
337  *
338  * \param tv pointer to ThreadVars
339  * \param data pointer that gets cast into PfringThreadVars for ptv
340  * \param slot slot containing task information
341  * \retval TM_ECODE_OK on success
342  * \retval TM_ECODE_FAILED on failure
343  */
344 TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot)
345 {
346  SCEnter();
347 
348  PfringThreadVars *ptv = (PfringThreadVars *)data;
349  Packet *p = NULL;
350  struct pfring_pkthdr hdr;
351  TmSlot *s = (TmSlot *)slot;
352  SCTime_t last_dump = SCTIME_INITIALIZER;
353  u_int buffer_size;
354  u_char *pkt_buffer;
355 
356  ptv->slot = s->slot_next;
357 
358  /* we have to enable the ring here as we need to do it after all
359  * the threads have called pfring_set_cluster(). */
360  int rc = pfring_enable_ring(ptv->pd);
361  if (rc != 0) {
362  SCLogError("pfring_enable_ring failed returned %d ", rc);
364  }
365 
366  // Indicate that the thread is actually running its application level code (i.e., it can poll
367  // packets)
369 
370  while(1) {
373  }
374 
375  /* make sure we have at least one packet in the packet pool, to prevent
376  * us from alloc'ing packets at line rate */
377  PacketPoolWait();
378 
380  if (p == NULL) {
382  }
384 
385  /* Some flavours of PF_RING may fail to set timestamp - see PF-RING-enabled libpcap code*/
386  hdr.ts.tv_sec = hdr.ts.tv_usec = 0;
387 
388  /* Check for Zero-copy mode */
389  if (ptv->flags & PFRING_FLAGS_ZERO_COPY) {
390  buffer_size = 0;
391  pkt_buffer = NULL;
392  } else {
393  buffer_size = GET_PKT_DIRECT_MAX_SIZE(p);
394  pkt_buffer = GET_PKT_DIRECT_DATA(p);
395  }
396 
397  int r = pfring_recv(ptv->pd, &pkt_buffer,
398  buffer_size,
399  &hdr,
401  if (likely(r == 1)) {
402  /* profiling started before blocking pfring_recv call, so
403  * reset it here */
405 
406 #ifdef HAVE_PF_RING_FLOW_OFFLOAD
407  if (ptv->flags & PFRING_FLAGS_BYPASS) {
408  /* pkt hash contains the flow id in this configuration */
409  p->pfring_v.flow_id = hdr.extended_hdr.pkt_hash;
410  p->pfring_v.ptv = ptv;
411  p->BypassPacketsFlow = PfringBypassCallback;
412  }
413 #endif
414 
415  /* Check for Zero-copy mode */
416  if (ptv->flags & PFRING_FLAGS_ZERO_COPY) {
417  PacketSetData(p, pkt_buffer, hdr.caplen);
418  }
419 
420  PfringProcessPacket(ptv, &hdr, p);
421 
422  if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
424  }
425 
426  /* Trigger one dump of stats every second */
427  if (SCTIME_CMP_NEQ(p->ts, last_dump)) {
428  PfringDumpCounters(ptv);
429  last_dump = p->ts;
430  }
431  } else if (unlikely(r == 0)) {
433  TmqhOutputPacketpool(ptv->tv, p);
435  }
436 
437  /* pfring didn't use the packet yet */
438  TmThreadsCaptureHandleTimeout(tv, p);
439 
440  } else {
441  SCLogError("pfring_recv error %" PRId32 "", r);
442  TmqhOutputPacketpool(ptv->tv, p);
444  }
446  }
447 
448  return TM_ECODE_OK;
449 }
450 
451 /**
452  * \brief Stop function for ReceivePfringLoop.
453  *
454  * This function forces ReceivePfringLoop to stop the
455  * execution, exiting the packet capture loop.
456  *
457  * \param tv pointer to ThreadVars
458  * \param data pointer that gets cast into PfringThreadVars for ptv
459  * \retval TM_ECODE_OK on success
460  * \retval TM_ECODE_FAILED on failure
461  */
463 {
464  PfringThreadVars *ptv = (PfringThreadVars *)data;
465 
466  /* Safety check */
467  if (ptv->pd == NULL) {
468  return TM_ECODE_FAILED;
469  }
470 
471  pfring_breakloop(ptv->pd);
472 
473  return TM_ECODE_OK;
474 }
475 
476 /**
477  * \brief Init function for ReceivePfring.
478  *
479  * This is a setup function for receiving packets
480  * via libpfring.
481  *
482  * \param tv pointer to ThreadVars
483  * \param initdata pointer to the interface passed from the user
484  * \param data pointer gets populated with PfringThreadVars
485  * \todo add a config option for setting cluster id
486  * \todo Create a general pfring setup function.
487  * \retval TM_ECODE_OK on success
488  * \retval TM_ECODE_FAILED on error
489  */
490 TmEcode ReceivePfringThreadInit(ThreadVars *tv, const void *initdata, void **data)
491 {
492  int rc;
493  u_int32_t version = 0;
494  PfringIfaceConfig *pfconf = (PfringIfaceConfig *) initdata;
495  unsigned int opflag;
496  char const *active_runmode = RunmodeGetActive();
497 
498  if (pfconf == NULL)
499  return TM_ECODE_FAILED;
500 
501  PfringThreadVars *ptv = SCCalloc(1, sizeof(PfringThreadVars));
502  if (unlikely(ptv == NULL)) {
503  pfconf->DerefFunc(pfconf);
504  return TM_ECODE_FAILED;
505  }
506 
507  ptv->tv = tv;
508  ptv->threads = 1;
509 
510  ptv->interface = SCStrdup(pfconf->iface);
511  if (unlikely(ptv->interface == NULL)) {
512  SCLogError("Unable to allocate device string");
513  SCFree(ptv);
515  }
516 
517  ptv->livedev = LiveGetDevice(pfconf->iface);
518  if (ptv->livedev == NULL) {
519  SCLogError("Unable to find Live device");
520  SCFree(ptv);
522  }
523 
524  /* enable zero-copy mode for workers runmode */
525  if (active_runmode && strcmp("workers", active_runmode) == 0) {
527  SCLogPerf("Enabling zero-copy for %s", ptv->interface);
528  }
529 
530  ptv->checksum_mode = pfconf->checksum_mode;
531 
532  opflag = PF_RING_PROMISC;
533 
534  /* if we have a recent kernel, we need to use parsed_pkt to get VLAN info */
535  if (ptv->vlan_in_ext_header) {
536  opflag |= PF_RING_LONG_HEADER;
537  }
538 
540  if (strncmp(ptv->interface, "dna", 3) == 0) {
541  SCLogWarning("Can't use rxonly checksum-checks on DNA interface,"
542  " resetting to auto");
544  } else {
545  opflag |= PF_RING_LONG_HEADER;
546  }
547  }
548 
549 #ifdef HAVE_PF_RING_FLOW_OFFLOAD
550  if (pfconf->flags & PFRING_CONF_FLAGS_BYPASS) {
551  opflag |= PF_RING_FLOW_OFFLOAD | PF_RING_FLOW_OFFLOAD_NOUPDATES;
552  ptv->flags |= PFRING_FLAGS_BYPASS;
553  }
554 #endif
555 
556  ptv->pd = pfring_open(ptv->interface, (uint32_t)default_packet_size, opflag);
557  if (ptv->pd == NULL) {
558  SCLogError("Failed to open %s: pfring_open error."
559  " Check if %s exists and pf_ring module is loaded.",
560  ptv->interface, ptv->interface);
561  pfconf->DerefFunc(pfconf);
562  SCFree(ptv);
563  return TM_ECODE_FAILED;
564  }
565 
566  pfring_set_application_name(ptv->pd, (char *)PROG_NAME);
567  pfring_version(ptv->pd, &version);
568 
569  /* We only set cluster info if the number of pfring threads is greater than 1 */
570  ptv->threads = pfconf->threads;
571 
572  ptv->cluster_id = pfconf->cluster_id;
573 
574  if ((ptv->threads == 1) && (strncmp(ptv->interface, "dna", 3) == 0)) {
575  SCLogInfo("DNA interface detected, not adding thread to cluster");
576  } else if (strncmp(ptv->interface, "zc", 2) == 0) {
577  SCLogInfo("ZC interface detected, not adding thread to cluster");
578  } else {
579  ptv->ctype = (cluster_type)pfconf->ctype;
580  rc = pfring_set_cluster(ptv->pd, ptv->cluster_id, ptv->ctype);
581 
582  if (rc != 0) {
583  SCLogError("pfring_set_cluster "
584  "returned %d for cluster-id: %d",
585  rc, ptv->cluster_id);
586  if (rc != PF_RING_ERROR_NOT_SUPPORTED || (pfconf->flags & PFRING_CONF_FLAGS_CLUSTER)) {
587  /* cluster is mandatory as explicitly specified in the configuration */
588  pfconf->DerefFunc(pfconf);
589  return TM_ECODE_FAILED;
590  }
591  }
592  }
593 
594  if (ptv->threads > 1) {
595  SCLogPerf("(%s) Using PF_RING v.%d.%d.%d, interface %s, cluster-id %d",
596  tv->name, (version & 0xFFFF0000) >> 16, (version & 0x0000FF00) >> 8,
597  version & 0x000000FF, ptv->interface, ptv->cluster_id);
598  } else {
599  SCLogPerf("(%s) Using PF_RING v.%d.%d.%d, interface %s, cluster-id %d, single-pfring-thread",
600  tv->name, (version & 0xFFFF0000) >> 16, (version & 0x0000FF00) >> 8,
601  version & 0x000000FF, ptv->interface, ptv->cluster_id);
602  }
603 
604  if (pfconf->bpf_filter) {
605  ptv->bpf_filter = SCStrdup(pfconf->bpf_filter);
606  if (unlikely(ptv->bpf_filter == NULL)) {
607  SCLogError("Set PF_RING bpf filter failed.");
608  } else {
609  SCMutexLock(&pfring_bpf_set_filter_lock);
610  rc = pfring_set_bpf_filter(ptv->pd, ptv->bpf_filter);
611  SCMutexUnlock(&pfring_bpf_set_filter_lock);
612 
613  if (rc < 0) {
614  SCLogError("Failed to compile BPF \"%s\"", ptv->bpf_filter);
615  return TM_ECODE_FAILED;
616  }
617  }
618  }
619 
620  ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets",
621  ptv->tv);
622  ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops",
623  ptv->tv);
624 #ifdef HAVE_PF_RING_FLOW_OFFLOAD
625  ptv->capture_bypassed = StatsRegisterCounter("capture.bypassed",
626  ptv->tv);
627 #endif
628 
629  /* If kernel is older than 3.0, VLAN is not stripped so we don't
630  * get the info from packet extended header but we will use a standard
631  * parsing */
632  ptv->vlan_in_ext_header = 1;
633  if (! SCKernelVersionIsAtLeast(3, 0)) {
634  ptv->vlan_in_ext_header = 0;
635  }
636 
637  /* If VLAN tags are not in the extended header, set cluster type to 5-tuple
638  * or in case of a ZC interface, do nothing */
639  if ((! ptv->vlan_in_ext_header) && ptv->ctype == CLUSTER_FLOW &&
640  strncmp(ptv->interface, "zc", 2) != 0) {
641  SCLogPerf("VLAN not in extended header, setting cluster type to CLUSTER_FLOW_5_TUPLE");
642  rc = pfring_set_cluster(ptv->pd, ptv->cluster_id, CLUSTER_FLOW_5_TUPLE);
643 
644  if (rc != 0) {
645  SCLogError("pfring_set_cluster "
646  "returned %d for cluster-id: %d",
647  rc, ptv->cluster_id);
648  pfconf->DerefFunc(pfconf);
649  return TM_ECODE_FAILED;
650  }
651  }
652 
654 
655  *data = (void *)ptv;
656  pfconf->DerefFunc(pfconf);
657 
658  return TM_ECODE_OK;
659 }
660 
661 /**
662  * \brief This function prints stats to the screen at exit.
663  * \param tv pointer to ThreadVars
664  * \param data pointer that gets cast into PfringThreadVars for ptv
665  */
667 {
668  PfringThreadVars *ptv = (PfringThreadVars *)data;
669 
670  PfringDumpCounters(ptv);
671  SCLogPerf("(%s) Kernel: Packets %" PRIu64 ", dropped %" PRIu64 "",
672  tv->name,
675  SCLogPerf("(%s) Packets %" PRIu64 ", bytes %" PRIu64 "", tv->name, ptv->pkts, ptv->bytes);
676 #ifdef HAVE_PF_RING_FLOW_OFFLOAD
677  if (ptv->flags & PFRING_FLAGS_BYPASS) {
678  SCLogPerf("(%s) Bypass: Packets %" PRIu64 "",
679  tv->name,
681  }
682 #endif
683 }
684 
685 /**
686  * \brief DeInit function closes pd at exit.
687  * \param tv pointer to ThreadVars
688  * \param data pointer that gets cast into PfringThreadVars for ptvi
689  * \retval TM_ECODE_OK is always returned
690  */
692 {
693  PfringThreadVars *ptv = (PfringThreadVars *)data;
694  if (ptv->interface)
695  SCFree(ptv->interface);
696  pfring_remove_from_cluster(ptv->pd);
697 
698  if (ptv->bpf_filter) {
699  pfring_remove_bpf_filter(ptv->pd);
700  SCFree(ptv->bpf_filter);
701  }
702 
703  pfring_close(ptv->pd);
704  SCFree(ptv);
705  return TM_ECODE_OK;
706 }
707 
708 /**
709  * \brief This function passes off to link type decoders.
710  *
711  * DecodePfring decodes raw packets from PF_RING. Inside of libpcap version of
712  * PF_RING all packets are marked as a link type of ethernet so that is what we do here.
713  *
714  * \param tv pointer to ThreadVars
715  * \param p pointer to the current packet
716  * \param data pointer that gets cast into PfringThreadVars for ptv
717  *
718  * \todo Verify that PF_RING only deals with ethernet traffic
719  *
720  * \warning This function bypasses the pkt buf and len macro's
721  *
722  * \retval TM_ECODE_OK is always returned
723  */
725 {
727 
729 
730  /* update counters */
732 
733  /* If suri has set vlan during reading, we increase vlan counter */
734  if (p->vlan_idx) {
736  }
737 
739 
741 
742  return TM_ECODE_OK;
743 }
744 
745 /**
746  * \brief This an Init function for DecodePfring
747  *
748  * \param tv pointer to ThreadVars
749  * \param initdata pointer to initialization data.
750  * \param data pointer that gets cast into PfringThreadVars for ptv
751  * \retval TM_ECODE_OK is returned on success
752  * \retval TM_ECODE_FAILED is returned on error
753  */
754 TmEcode DecodePfringThreadInit(ThreadVars *tv, const void *initdata, void **data)
755 {
756  DecodeThreadVars *dtv = NULL;
757 
759  if (dtv == NULL)
761 
763 
764  *data = (void *)dtv;
765 
766  return TM_ECODE_OK;
767 }
768 
770 {
771  if (data != NULL)
772  DecodeThreadVarsFree(tv, data);
774 }
775 
776 #endif /* HAVE_PFRING */
777 /* eof */
TmModule_::cap_flags
uint8_t cap_flags
Definition: tm-modules.h:74
PKT_IS_UDP
#define PKT_IS_UDP(p)
Definition: decode.h:249
tm-threads.h
max_pending_packets
uint16_t max_pending_packets
Definition: suricata.c:186
ReceivePfringThreadInit
TmEcode ReceivePfringThreadInit(ThreadVars *, const void *, void **)
Init function for ReceivePfring.
Definition: source-pfring.c:490
PfringIfaceConfig_
Definition: source-pfring.h:36
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:167
SCTIME_CMP_NEQ
#define SCTIME_CMP_NEQ(a, b)
Definition: util-time.h:107
ThreadVars_::name
char name[16]
Definition: threadvars.h:64
PfringThreadVars_::cluster_id
uint8_t cluster_id
Definition: source-pfring.c:148
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1075
PfringIfaceConfig_::cluster_id
int cluster_id
Definition: source-pfring.h:40
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
ReceivePfringLoop
TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot)
Receives packets from an interface via libpfring.
Definition: source-pfring.c:344
ReceivePfringThreadExitStats
void ReceivePfringThreadExitStats(ThreadVars *, void *)
This function prints stats to the screen at exit.
Definition: source-pfring.c:666
PfringBreakLoop
TmEcode PfringBreakLoop(ThreadVars *tv, void *data)
Stop function for ReceivePfringLoop.
Definition: source-pfring.c:462
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
DecodePfringThreadDeinit
TmEcode DecodePfringThreadDeinit(ThreadVars *tv, void *data)
Definition: source-pfring.c:769
TmThreadsSetFlag
void TmThreadsSetFlag(ThreadVars *tv, uint32_t flag)
Set a thread flag.
Definition: tm-threads.c:99
TMM_DECODEPFRING
@ TMM_DECODEPFRING
Definition: tm-threads-common.h:43
util-checksum.h
Packet_::flags
uint32_t flags
Definition: decode.h:474
threads.h
TMM_RECEIVEPFRING
@ TMM_RECEIVEPFRING
Definition: tm-threads-common.h:42
Packet_::vlan_idx
uint8_t vlan_idx
Definition: decode.h:465
PfringThreadVars_::tv
ThreadVars * tv
Definition: source-pfring.c:138
PACKET_PROFILING_RESTART
#define PACKET_PROFILING_RESTART(p)
Definition: util-profiling.h:80
LiveDevice_
Definition: util-device.h:50
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:332
PfringThreadVars_::livedev
LiveDevice * livedev
Definition: source-pfring.c:150
StatsSetUI64
void StatsSetUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Sets a value of type double to the local counter.
Definition: counters.c:210
THV_RUNNING
#define THV_RUNNING
Definition: threadvars.h:54
PfringThreadVars_::ctype
cluster_type ctype
Definition: source-pfring.c:146
packet-queue.h
CHECKSUM_VALIDATION_RXONLY
@ CHECKSUM_VALIDATION_RXONLY
Definition: decode.h:49
SURICATA_STOP
#define SURICATA_STOP
Definition: suricata.h:89
SCKernelVersionIsAtLeast
int SCKernelVersionIsAtLeast(int major, int minor)
Definition: util-host-info.c:37
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
PfringThreadVars_::vlan_hdr_warned
bool vlan_hdr_warned
Definition: source-pfring.c:156
util-privs.h
PfringThreadVars_::slot
TmSlot * slot
Definition: source-pfring.c:139
CHECKSUM_VALIDATION_DISABLE
@ CHECKSUM_VALIDATION_DISABLE
Definition: decode.h:46
SCMUTEX_INITIALIZER
#define SCMUTEX_INITIALIZER
Definition: threads-debug.h:121
SC_CAP_NET_BROADCAST
#define SC_CAP_NET_BROADCAST
Definition: util-privs.h:34
PacketDecodeFinalize
void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Finalize decoding of a packet.
Definition: decode.c:203
RunmodeGetActive
char * RunmodeGetActive(void)
Definition: runmodes.c:217
TmqhOutputPacketpool
void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
Definition: tmqh-packetpool.c:317
Packet_::BypassPacketsFlow
int(* BypassPacketsFlow)(struct Packet_ *)
Definition: decode.h:532
TmModuleReceivePfringRegister
void TmModuleReceivePfringRegister(void)
Registration Function for ReceivePfring.
Definition: source-pfring.c:163
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:85
PfringThreadVars_::pd
pfring * pd
Definition: source-pfring.c:126
GET_PKT_DIRECT_MAX_SIZE
#define GET_PKT_DIRECT_MAX_SIZE(p)
Definition: decode.h:223
ChecksumAutoModeCheck
int ChecksumAutoModeCheck(uint64_t thread_count, uint64_t iface_count, uint64_t iface_fail)
Check if the number of invalid checksums indicate checksum offloading in place.
Definition: util-checksum.c:69
TmModule_::PktAcqLoop
TmEcode(* PktAcqLoop)(ThreadVars *, void *, void *)
Definition: tm-modules.h:55
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:84
TmModule_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:50
Packet_::datalink
int datalink
Definition: decode.h:620
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1078
SC_CAP_NET_BIND_SERVICE
#define SC_CAP_NET_BIND_SERVICE
Definition: util-privs.h:33
PKT_IS_TCP
#define PKT_IS_TCP(p)
Definition: decode.h:248
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:599
PfringIfaceConfig_::iface
char iface[PFRING_IFACE_NAME_LENGTH]
Definition: source-pfring.h:43
CHECKSUM_VALIDATION_AUTO
@ CHECKSUM_VALIDATION_AUTO
Definition: decode.h:48
SET_PKT_LEN
#define SET_PKT_LEN(p, len)
Definition: decode.h:225
decode.h
util-device.h
util-debug.h
PKT_SRC_WIRE
@ PKT_SRC_WIRE
Definition: decode.h:55
TmModule_::PktAcqBreakLoop
TmEcode(* PktAcqBreakLoop)(ThreadVars *, void *)
Definition: tm-modules.h:58
PfringThreadVars_::threads
int threads
Definition: source-pfring.c:144
Packet_::ts
SCTime_t ts
Definition: decode.h:485
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
LiveGetDevice
LiveDevice * LiveGetDevice(const char *name)
Get a pointer to the device at idx.
Definition: util-device.c:248
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
GET_PKT_DATA
#define GET_PKT_DATA(p)
Definition: decode.h:221
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
SCTIME_FROM_TIMEVAL
#define SCTIME_FROM_TIMEVAL(tv)
Definition: util-time.h:79
TmModule_::Func
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition: tm-modules.h:53
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
SC_CAP_NET_ADMIN
#define SC_CAP_NET_ADMIN
Definition: util-privs.h:31
source-pfring.h
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:300
PfringIfaceConfig_::bpf_filter
const char * bpf_filter
Definition: source-pfring.h:47
util-profiling.h
StatsGetLocalCounterValue
uint64_t StatsGetLocalCounterValue(ThreadVars *tv, uint16_t id)
Get the value of the local copy of the counter that hold this id.
Definition: counters.c:1270
PFRING_CONF_FLAGS_CLUSTER
#define PFRING_CONF_FLAGS_CLUSTER
Definition: source-pfring.h:32
PacketPoolWait
void PacketPoolWait(void)
Definition: tmqh-packetpool.c:80
DecodePfringThreadInit
TmEcode DecodePfringThreadInit(ThreadVars *, const void *, void **)
This an Init function for DecodePfring.
Definition: source-pfring.c:754
Packet_
Definition: decode.h:437
TM_FLAG_DECODE_TM
#define TM_FLAG_DECODE_TM
Definition: tm-modules.h:33
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:33
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:220
conf.h
TmSlot_
Definition: tm-threads.h:53
PKT_IGNORE_CHECKSUM
#define PKT_IGNORE_CHECKSUM
Definition: decode.h:1038
SCTime_t
Definition: util-time.h:40
Packet_::livedev
struct LiveDevice_ * livedev
Definition: decode.h:599
TmEcode
TmEcode
Definition: tm-threads-common.h:83
util-host-info.h
TmModule_::name
const char * name
Definition: tm-modules.h:45
PFRING_CONF_FLAGS_BYPASS
#define PFRING_CONF_FLAGS_BYPASS
Definition: source-pfring.h:33
PfringThreadVars_::capture_bypassed
uint16_t capture_bypassed
Definition: source-pfring.c:134
DecodeThreadVars_::counter_vlan
uint16_t counter_vlan
Definition: decode.h:721
runmodes.h
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:224
TM_FLAG_RECEIVE_TM
#define TM_FLAG_RECEIVE_TM
Definition: tm-modules.h:32
ReceivePfringThreadDeinit
TmEcode ReceivePfringThreadDeinit(ThreadVars *, void *)
DeInit function closes pd at exit.
Definition: source-pfring.c:691
PfringThreadVars_
Structure to hold thread specific variables.
Definition: source-pfring.c:124
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
default_packet_size
uint32_t default_packet_size
Definition: decode.c:76
tm-queuehandlers.h
PfringIfaceConfig_::flags
uint32_t flags
Definition: source-pfring.h:37
PROG_NAME
#define PROG_NAME
Definition: suricata.h:70
PfringThreadVars_::interface
char * interface
Definition: source-pfring.c:149
DecodeThreadVarsFree
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:787
ChecksumValidationMode
ChecksumValidationMode
Definition: decode.h:45
suricata-common.h
CLUSTER_FLOW_5_TUPLE
#define CLUSTER_FLOW_5_TUPLE
Definition: source-pfring.h:79
SCLogPerf
#define SCLogPerf(...)
Definition: util-debug.h:230
version
uint8_t version
Definition: decode-gre.h:1
PfringIfaceConfig_::DerefFunc
void(* DerefFunc)(void *)
Definition: source-pfring.h:51
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:48
TmModuleDecodePfringRegister
void TmModuleDecodePfringRegister(void)
Registration Function for DecodePfring.
Definition: source-pfring.c:179
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
PfringThreadVars_::flags
uint32_t flags
Definition: source-pfring.c:136
TmModule_::ThreadExitPrintStats
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:49
threadvars.h
PfringIfaceConfig_::threads
int threads
Definition: source-pfring.h:45
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:685
PfringThreadVars_::capture_kernel_drops
uint16_t capture_kernel_drops
Definition: source-pfring.c:133
PFRING_FLAGS_ZERO_COPY
#define PFRING_FLAGS_ZERO_COPY
Definition: source-pfring.c:117
PfringThreadVars_::vlan_in_ext_header
int vlan_in_ext_header
Definition: source-pfring.c:141
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:769
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:807
GET_PKT_DIRECT_DATA
#define GET_PKT_DIRECT_DATA(p)
Definition: decode.h:222
PfringThreadVars_::bpf_filter
char * bpf_filter
Definition: source-pfring.c:152
PfringThreadVars_::bytes
uint64_t bytes
Definition: source-pfring.c:129
suricata.h
PfringThreadVars_::checksum_mode
ChecksumValidationMode checksum_mode
Definition: source-pfring.c:154
Packet_::vlan_id
uint16_t vlan_id[VLAN_MAX_LAYERS]
Definition: decode.h:464
CLUSTER_FLOW
#define CLUSTER_FLOW
Definition: source-pfring.h:77
likely
#define likely(expr)
Definition: util-optimize.h:32
TmSlot_::slot_next
struct TmSlot_ * slot_next
Definition: tm-threads.h:62
StatsSyncCountersIfSignalled
void StatsSyncCountersIfSignalled(ThreadVars *tv)
Definition: counters.c:461
PfringThreadVars_::capture_kernel_packets
uint16_t capture_kernel_packets
Definition: source-pfring.c:132
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:375
LIBPFRING_WAIT_FOR_INCOMING
#define LIBPFRING_WAIT_FOR_INCOMING
Definition: source-pfring.c:114
SCTIME_INITIALIZER
#define SCTIME_INITIALIZER
Definition: util-time.h:51
PfringThreadVars_::pkts
uint64_t pkts
Definition: source-pfring.c:130
StatsRegisterCounter
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:971
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
PfringIfaceConfig_::checksum_mode
ChecksumValidationMode checksum_mode
Definition: source-pfring.h:49
DecodePfring
TmEcode DecodePfring(ThreadVars *, Packet *, void *)
This function passes off to link type decoders.
Definition: source-pfring.c:724
SCMutex
#define SCMutex
Definition: threads-debug.h:114
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:264
SC_CAP_NET_RAW
#define SC_CAP_NET_RAW
Definition: util-privs.h:32
DecodeEthernet
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-ethernet.c:42
PFRING_FLAGS_BYPASS
#define PFRING_FLAGS_BYPASS
Definition: source-pfring.c:118
TmModule_::flags
uint8_t flags
Definition: tm-modules.h:77
DecodeUpdatePacketCounters
void DecodeUpdatePacketCounters(ThreadVars *tv, const DecodeThreadVars *dtv, const Packet *p)
Definition: decode.c:735
LINKTYPE_ETHERNET
#define LINKTYPE_ETHERNET
Definition: decode.h:989
suricata_ctl_flags
volatile uint8_t suricata_ctl_flags
Definition: suricata.c:172
PfringIfaceConfig_::ctype
unsigned int ctype
Definition: source-pfring.h:41