suricata
source-pfring.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2017 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-device.h"
45 #include "util-host-info.h"
46 #include "runmodes.h"
47 #include "util-profiling.h"
48 
49 TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot);
50 TmEcode PfringBreakLoop(ThreadVars *tv, void *data);
51 TmEcode ReceivePfringThreadInit(ThreadVars *, const void *, void **);
54 
55 TmEcode DecodePfringThreadInit(ThreadVars *, const void *, void **);
58 
59 extern int max_pending_packets;
60 
61 #ifndef HAVE_PFRING
62 
63 /*Handle cases where we don't have PF_RING support built-in*/
64 TmEcode NoPfringSupportExit(ThreadVars *, const void *, void **);
65 
67 {
68  tmm_modules[TMM_RECEIVEPFRING].name = "ReceivePfring";
69  tmm_modules[TMM_RECEIVEPFRING].ThreadInit = NoPfringSupportExit;
77 }
78 
80 {
81  tmm_modules[TMM_DECODEPFRING].name = "DecodePfring";
82  tmm_modules[TMM_DECODEPFRING].ThreadInit = NoPfringSupportExit;
89 }
90 
91 /**
92  * \brief this funciton prints an error message and exits.
93  * \param tv pointer to ThreadVars
94  * \param initdata pointer to the interface passed from the user
95  * \param data pointer gets populated with PfringThreadVars
96  */
97 TmEcode NoPfringSupportExit(ThreadVars *tv, const void *initdata, void **data)
98 {
99  SCLogError(SC_ERR_NO_PF_RING,"Error creating thread %s: you do not have support for pfring "
100  "enabled please recompile with --enable-pfring", 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  */
123 typedef struct PfringThreadVars_
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 
158 
159 /**
160  * \brief Registration Function for RecievePfring.
161  * \todo Unit tests are needed for this module.
162  */
164 {
165  tmm_modules[TMM_RECEIVEPFRING].name = "ReceivePfring";
174 }
175 
176 /**
177  * \brief Registration Function for DecodePfring.
178  * \todo Unit tests are needed for this module.
179  */
181 {
182  tmm_modules[TMM_DECODEPFRING].name = "DecodePfring";
189 }
190 
191 static inline void PfringDumpCounters(PfringThreadVars *ptv)
192 {
193  pfring_stat pfring_s;
194  if (likely((pfring_stats(ptv->pd, &pfring_s) >= 0))) {
195  /* pfring counter is per socket and is not cleared after read.
196  * So to get the number of packet on the interface we can add
197  * the newly seen packets and drops for this thread and add it
198  * to the interface counter */
199  uint64_t th_pkts = StatsGetLocalCounterValue(ptv->tv, ptv->capture_kernel_packets);
200  uint64_t th_drops = StatsGetLocalCounterValue(ptv->tv, ptv->capture_kernel_drops);
201  SC_ATOMIC_ADD(ptv->livedev->pkts, pfring_s.recv - th_pkts);
202  SC_ATOMIC_ADD(ptv->livedev->drop, pfring_s.drop - th_drops);
203  StatsSetUI64(ptv->tv, ptv->capture_kernel_packets, pfring_s.recv);
204  StatsSetUI64(ptv->tv, ptv->capture_kernel_drops, pfring_s.drop);
205 
206 #ifdef HAVE_PF_RING_FLOW_OFFLOAD
207  if (ptv->flags & PFRING_FLAGS_BYPASS) {
208  uint64_t th_bypassed = StatsGetLocalCounterValue(ptv->tv, ptv->capture_bypassed);
209  SC_ATOMIC_ADD(ptv->livedev->bypassed, pfring_s.shunt - th_bypassed);
210  StatsSetUI64(ptv->tv, ptv->capture_bypassed, pfring_s.shunt);
211  }
212 #endif
213  }
214 }
215 
216 /**
217  * \brief Pfring Packet Process function.
218  *
219  * This function fills in our packet structure from libpfring.
220  * From here the packets are picked up by the DecodePfring thread.
221  *
222  * \param user pointer to PfringThreadVars
223  * \param h pointer to pfring packet header
224  * \param p pointer to the current packet
225  */
226 static inline void PfringProcessPacket(void *user, struct pfring_pkthdr *h, Packet *p)
227 {
228  PfringThreadVars *ptv = (PfringThreadVars *)user;
229 
230  ptv->bytes += h->caplen;
231  ptv->pkts++;
232  p->livedev = ptv->livedev;
233 
234  /* PF_RING may fail to set timestamp */
235  if (h->ts.tv_sec == 0) {
236  gettimeofday((struct timeval *)&h->ts, NULL);
237  }
238 
239  p->ts.tv_sec = h->ts.tv_sec;
240  p->ts.tv_usec = h->ts.tv_usec;
241 
242  /* PF_RING all packets are marked as a link type of ethernet
243  * so that is what we do here. */
245 
246  /* In the past, we needed this vlan handling in cases
247  * where the vlan header was stripped from the raw packet.
248  * With modern (at least >= 6) versions of PF_RING, the
249  * 'copy_data_to_ring' function (kernel/pf_ring.c) makes
250  * sure that if the hardware stripped the vlan header,
251  * it is put back by PF_RING.
252  *
253  * PF_RING should put it back in all cases, but as a extra
254  * precaution keep the check here. If the vlan header is
255  * part of the raw packet, the vlan_offset will be set.
256  * So is it is not set, use the parsed info from PF_RING's
257  * extended header.
258  */
259  if ((!ptv->vlan_disabled) &&
260  h->extended_hdr.parsed_pkt.offset.vlan_offset == 0 &&
261  h->extended_hdr.parsed_pkt.vlan_id)
262  {
263  p->vlan_id[0] = h->extended_hdr.parsed_pkt.vlan_id & 0x0fff;
264  p->vlan_idx = 1;
265  p->vlanh[0] = NULL;
266 
267  if (!ptv->vlan_hdr_warned) {
268  SCLogWarning(SC_ERR_PF_RING_VLAN, "no VLAN header in the raw "
269  "packet. See #2355.");
270  ptv->vlan_hdr_warned = true;
271  }
272  }
273 
274  switch (ptv->checksum_mode) {
276  if (h->extended_hdr.rx_direction == 0) {
278  }
279  break;
282  break;
284  if (ptv->livedev->ignore_checksum) {
286  } else if (ChecksumAutoModeCheck(ptv->pkts,
287  SC_ATOMIC_GET(ptv->livedev->pkts),
288  SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
289  ptv->livedev->ignore_checksum = 1;
291  }
292  break;
293  default:
294  break;
295  }
296 
297  SET_PKT_LEN(p, h->caplen);
298 }
299 
300 #ifdef HAVE_PF_RING_FLOW_OFFLOAD
301 /**
302  * \brief Pfring bypass callback function
303  *
304  * \param p a Packet to use information from to trigger bypass
305  * \return 1 if bypass is successful, 0 if not
306  */
307 static int PfringBypassCallback(Packet *p)
308 {
309  hw_filtering_rule r;
310 
311  /* Only bypass TCP and UDP */
312  if (!(PKT_IS_TCP(p) || PKT_IS_UDP(p))) {
313  return 0;
314  }
315 
316  /* Bypassing tunneled packets is currently not supported */
317  if (IS_TUNNEL_PKT(p)) {
318  return 0;
319  }
320 
321  r.rule_family_type = generic_flow_id_rule;
322  r.rule_family.flow_id_rule.action = flow_drop_rule;
323  r.rule_family.flow_id_rule.thread = 0;
324  r.rule_family.flow_id_rule.flow_id = p->pfring_v.flow_id;
325 
326  SCLogDebug("Bypass set for flow ID = %u", p->pfring_v.flow_id);
327 
328  if (pfring_add_hw_rule(p->pfring_v.ptv->pd, &r) < 0) {
329  return 0;
330  }
331 
332  return 1;
333 }
334 #endif
335 
336 /**
337  * \brief Recieves packets from an interface via libpfring.
338  *
339  * This function recieves packets from an interface and passes
340  * the packet on to the pfring callback function.
341  *
342  * \param tv pointer to ThreadVars
343  * \param data pointer that gets cast into PfringThreadVars for ptv
344  * \param slot slot containing task information
345  * \retval TM_ECODE_OK on success
346  * \retval TM_ECODE_FAILED on failure
347  */
349 {
350  SCEnter();
351 
352  PfringThreadVars *ptv = (PfringThreadVars *)data;
353  Packet *p = NULL;
354  struct pfring_pkthdr hdr;
355  TmSlot *s = (TmSlot *)slot;
356  time_t last_dump = 0;
357  u_int buffer_size;
358  u_char *pkt_buffer;
359 
360  ptv->slot = s->slot_next;
361 
362  /* we have to enable the ring here as we need to do it after all
363  * the threads have called pfring_set_cluster(). */
364  int rc = pfring_enable_ring(ptv->pd);
365  if (rc != 0) {
366  SCLogError(SC_ERR_PF_RING_OPEN, "pfring_enable_ring failed returned %d ", rc);
368  }
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) {
423  TmqhOutputPacketpool(ptv->tv, p);
425  }
426 
427  /* Trigger one dump of stats every second */
428  if (p->ts.tv_sec != last_dump) {
429  PfringDumpCounters(ptv);
430  last_dump = p->ts.tv_sec;
431  }
432  } else if (unlikely(r == 0)) {
433  if (suricata_ctl_flags & SURICATA_STOP) {
435  }
436 
437  /* pfring didn't use the packet yet */
438  TmThreadsCaptureInjectPacket(tv, ptv->slot, p);
439 
440  } else {
441  SCLogError(SC_ERR_PF_RING_RECV,"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 RecievePfring.
478  *
479  * This is a setup function for recieving 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 
502  if (unlikely(ptv == NULL)) {
503  pfconf->DerefFunc(pfconf);
504  return TM_ECODE_FAILED;
505  }
506  memset(ptv, 0, sizeof(PfringThreadVars));
507 
508  ptv->tv = tv;
509  ptv->threads = 1;
510 
511  ptv->interface = SCStrdup(pfconf->iface);
512  if (unlikely(ptv->interface == NULL)) {
513  SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate device string");
514  SCFree(ptv);
516  }
517 
518  ptv->livedev = LiveGetDevice(pfconf->iface);
519  if (ptv->livedev == NULL) {
520  SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device");
521  SCFree(ptv);
523  }
524 
525  /* enable zero-copy mode for workers runmode */
526  if (active_runmode && strcmp("workers", active_runmode) == 0) {
528  SCLogPerf("Enabling zero-copy for %s", ptv->interface);
529  }
530 
531  ptv->checksum_mode = pfconf->checksum_mode;
532 
533  opflag = PF_RING_PROMISC;
534 
535  /* if suri uses VLAN and if we have a recent kernel, we need
536  * to use parsed_pkt to get VLAN info */
537  if ((! ptv->vlan_disabled) && SCKernelVersionIsAtLeast(3, 0)) {
538  opflag |= PF_RING_LONG_HEADER;
539  }
540 
542  if (strncmp(ptv->interface, "dna", 3) == 0) {
544  "Can't use rxonly checksum-checks on DNA interface,"
545  " resetting to auto");
547  } else {
548  opflag |= PF_RING_LONG_HEADER;
549  }
550  }
551 
552 #ifdef HAVE_PF_RING_FLOW_OFFLOAD
553  if (pfconf->flags & PFRING_CONF_FLAGS_BYPASS) {
554  opflag |= PF_RING_FLOW_OFFLOAD | PF_RING_FLOW_OFFLOAD_NOUPDATES;
555  ptv->flags |= PFRING_FLAGS_BYPASS;
556  }
557 #endif
558 
559  ptv->pd = pfring_open(ptv->interface, (uint32_t)default_packet_size, opflag);
560  if (ptv->pd == NULL) {
561  SCLogError(SC_ERR_PF_RING_OPEN,"Failed to open %s: pfring_open error."
562  " Check if %s exists and pf_ring module is loaded.",
563  ptv->interface,
564  ptv->interface);
565  pfconf->DerefFunc(pfconf);
566  SCFree(ptv);
567  return TM_ECODE_FAILED;
568  }
569 
570  pfring_set_application_name(ptv->pd, (char *)PROG_NAME);
571  pfring_version(ptv->pd, &version);
572 
573  /* We only set cluster info if the number of pfring threads is greater than 1 */
574  ptv->threads = pfconf->threads;
575 
576  ptv->cluster_id = pfconf->cluster_id;
577 
578  if ((ptv->threads == 1) && (strncmp(ptv->interface, "dna", 3) == 0)) {
579  SCLogInfo("DNA interface detected, not adding thread to cluster");
580  } else if (strncmp(ptv->interface, "zc", 2) == 0) {
581  SCLogInfo("ZC interface detected, not adding thread to cluster");
582  } else {
583  ptv->ctype = (cluster_type)pfconf->ctype;
584  rc = pfring_set_cluster(ptv->pd, ptv->cluster_id, ptv->ctype);
585 
586  if (rc != 0) {
587  SCLogError(SC_ERR_PF_RING_SET_CLUSTER_FAILED, "pfring_set_cluster "
588  "returned %d for cluster-id: %d", rc, ptv->cluster_id);
589  if (rc != PF_RING_ERROR_NOT_SUPPORTED || (pfconf->flags & PFRING_CONF_FLAGS_CLUSTER)) {
590  /* cluster is mandatory as explicitly specified in the configuration */
591  pfconf->DerefFunc(pfconf);
592  return TM_ECODE_FAILED;
593  }
594  }
595  }
596 
597  if (ptv->threads > 1) {
598  SCLogPerf("(%s) Using PF_RING v.%d.%d.%d, interface %s, cluster-id %d",
599  tv->name, (version & 0xFFFF0000) >> 16, (version & 0x0000FF00) >> 8,
600  version & 0x000000FF, ptv->interface, ptv->cluster_id);
601  } else {
602  SCLogPerf("(%s) Using PF_RING v.%d.%d.%d, interface %s, cluster-id %d, single-pfring-thread",
603  tv->name, (version & 0xFFFF0000) >> 16, (version & 0x0000FF00) >> 8,
604  version & 0x000000FF, ptv->interface, ptv->cluster_id);
605  }
606 
607  if (pfconf->bpf_filter) {
608  ptv->bpf_filter = SCStrdup(pfconf->bpf_filter);
609  if (unlikely(ptv->bpf_filter == NULL)) {
610  SCLogError(SC_ERR_MEM_ALLOC, "Set PF_RING bpf filter failed.");
611  } else {
612  SCMutexLock(&pfring_bpf_set_filter_lock);
613  rc = pfring_set_bpf_filter(ptv->pd, ptv->bpf_filter);
614  SCMutexUnlock(&pfring_bpf_set_filter_lock);
615 
616  if (rc < 0) {
617  SCLogInfo("Set PF_RING bpf filter \"%s\" failed.",
618  ptv->bpf_filter);
619  }
620  }
621  }
622 
623  ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets",
624  ptv->tv);
625  ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops",
626  ptv->tv);
627 #ifdef HAVE_PF_RING_FLOW_OFFLOAD
628  ptv->capture_bypassed = StatsRegisterCounter("capture.bypassed",
629  ptv->tv);
630 #endif
631 
632  /* A bit strange to have this here but we only have vlan information
633  * during reading so we need to know if we want to keep vlan during
634  * the capture phase */
635  int vlanbool = 0;
636  if ((ConfGetBool("vlan.use-for-tracking", &vlanbool)) == 1 && vlanbool == 0) {
637  ptv->vlan_disabled = 1;
638  }
639 
640  /* If kernel is older than 3.8, VLAN is not stripped so we don't
641  * get the info from packt extended header but we will use a standard
642  * parsing */
643  if (! SCKernelVersionIsAtLeast(3, 0)) {
644  ptv->vlan_disabled = 1;
645  }
646 
647  /* If VLAN tracking is disabled, set cluster type to 5-tuple or in case of a
648  * ZC interface, do nothing */
649  if (ptv->vlan_disabled && ptv->ctype == CLUSTER_FLOW &&
650  strncmp(ptv->interface, "zc", 2) != 0) {
651  SCLogPerf("VLAN disabled, setting cluster type to CLUSTER_FLOW_5_TUPLE");
652  rc = pfring_set_cluster(ptv->pd, ptv->cluster_id, CLUSTER_FLOW_5_TUPLE);
653 
654  if (rc != 0) {
655  SCLogError(SC_ERR_PF_RING_SET_CLUSTER_FAILED, "pfring_set_cluster "
656  "returned %d for cluster-id: %d", rc, ptv->cluster_id);
657  pfconf->DerefFunc(pfconf);
658  return TM_ECODE_FAILED;
659  }
660  }
661 
662  *data = (void *)ptv;
663  pfconf->DerefFunc(pfconf);
664 
665  return TM_ECODE_OK;
666 }
667 
668 /**
669  * \brief This function prints stats to the screen at exit.
670  * \param tv pointer to ThreadVars
671  * \param data pointer that gets cast into PfringThreadVars for ptv
672  */
674 {
675  PfringThreadVars *ptv = (PfringThreadVars *)data;
676 
677  PfringDumpCounters(ptv);
678  SCLogPerf("(%s) Kernel: Packets %" PRIu64 ", dropped %" PRIu64 "",
679  tv->name,
682  SCLogPerf("(%s) Packets %" PRIu64 ", bytes %" PRIu64 "", tv->name, ptv->pkts, ptv->bytes);
683 #ifdef HAVE_PF_RING_FLOW_OFFLOAD
684  if (ptv->flags & PFRING_FLAGS_BYPASS) {
685  SCLogPerf("(%s) Bypass: Packets %" PRIu64 "",
686  tv->name,
688  }
689 #endif
690 }
691 
692 /**
693  * \brief DeInit function closes pd at exit.
694  * \param tv pointer to ThreadVars
695  * \param data pointer that gets cast into PfringThreadVars for ptvi
696  * \retval TM_ECODE_OK is always returned
697  */
699 {
700  PfringThreadVars *ptv = (PfringThreadVars *)data;
701  if (ptv->interface)
702  SCFree(ptv->interface);
703  pfring_remove_from_cluster(ptv->pd);
704 
705  if (ptv->bpf_filter) {
706  pfring_remove_bpf_filter(ptv->pd);
707  SCFree(ptv->bpf_filter);
708  }
709 
710  pfring_close(ptv->pd);
711  return TM_ECODE_OK;
712 }
713 
714 /**
715  * \brief This function passes off to link type decoders.
716  *
717  * DecodePfring reads packets from the PacketQueue. Inside of libpcap version of
718  * PF_RING all packets are marked as a link type of ethernet so that is what we do here.
719  *
720  * \param tv pointer to ThreadVars
721  * \param p pointer to the current packet
722  * \param data pointer that gets cast into PfringThreadVars for ptv
723  * \param pq pointer to the current PacketQueue
724  *
725  * \todo Verify that PF_RING only deals with ethernet traffic
726  *
727  * \warning This function bypasses the pkt buf and len macro's
728  *
729  * \retval TM_ECODE_OK is always returned
730  */
732 {
733  DecodeThreadVars *dtv = (DecodeThreadVars *)data;
734 
735  /* XXX HACK: flow timeout can call us for injected pseudo packets
736  * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */
737  if (p->flags & PKT_PSEUDO_STREAM_END)
738  return TM_ECODE_OK;
739 
740  /* update counters */
741  DecodeUpdatePacketCounters(tv, dtv, p);
742 
743  /* If suri has set vlan during reading, we increase vlan counter */
744  if (p->vlan_idx) {
745  StatsIncr(tv, dtv->counter_vlan);
746  }
747 
748  DecodeEthernet(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
749 
750  PacketDecodeFinalize(tv, dtv, p);
751 
752  return TM_ECODE_OK;
753 }
754 
755 /**
756  * \brief This an Init function for DecodePfring
757  *
758  * \param tv pointer to ThreadVars
759  * \param initdata pointer to initilization data.
760  * \param data pointer that gets cast into PfringThreadVars for ptv
761  * \retval TM_ECODE_OK is returned on success
762  * \retval TM_ECODE_FAILED is returned on error
763  */
764 TmEcode DecodePfringThreadInit(ThreadVars *tv, const void *initdata, void **data)
765 {
766  DecodeThreadVars *dtv = NULL;
767 
768  dtv = DecodeThreadVarsAlloc(tv);
769  if (dtv == NULL)
771 
773 
774  *data = (void *)dtv;
775 
776  return TM_ECODE_OK;
777 }
778 
780 {
781  if (data != NULL)
782  DecodeThreadVarsFree(tv, data);
784 }
785 
786 #endif /* HAVE_PFRING */
787 /* eof */
#define PFRING_CONF_FLAGS_BYPASS
Definition: source-pfring.h:35
ChecksumValidationMode checksum_mode
TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot)
Recieves packets from an interface via libpfring.
#define TM_FLAG_DECODE_TM
Definition: tm-modules.h:32
#define GET_PKT_DIRECT_MAX_SIZE(p)
Definition: decode.h:226
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:570
#define SCLogDebug(...)
Definition: util-debug.h:335
#define PROG_NAME
Definition: suricata.h:71
cluster_type ctype
#define SC_CAP_NET_BROADCAST
Definition: util-privs.h:34
int(* BypassPacketsFlow)(struct Packet_ *)
Definition: decode.h:490
TmEcode PfringBreakLoop(ThreadVars *tv, void *data)
Stop function for ReceivePfringLoop.
unsigned int ctype
Definition: source-pfring.h:43
uint8_t cap_flags
Definition: tm-modules.h:67
uint8_t flags
Definition: tm-modules.h:70
#define SET_PKT_LEN(p, len)
Definition: decode.h:228
void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Finalize decoding of a packet.
Definition: decode.c:114
#define unlikely(expr)
Definition: util-optimize.h:35
TmEcode(* Func)(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *)
Definition: tm-modules.h:52
int ConfGetBool(const char *name, int *val)
Retrieve a configuration value as an boolen.
Definition: conf.c:517
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:431
#define PACKET_PROFILING_RESTART(p)
TmEcode ReceivePfringThreadInit(ThreadVars *, const void *, void **)
Init function for RecievePfring.
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:108
TmEcode DecodePfringThreadInit(ThreadVars *, const void *, void **)
This an Init function for DecodePfring.
ThreadVars * tv
#define LIBPFRING_WAIT_FOR_INCOMING
#define IS_TUNNEL_PKT(p)
Definition: decode.h:894
LiveDevice * livedev
TmEcode DecodePfringThreadDeinit(ThreadVars *tv, void *data)
volatile uint8_t suricata_ctl_flags
Definition: suricata.c:201
#define SC_CAP_NET_ADMIN
Definition: util-privs.h:31
#define SC_CAP_NET_BIND_SERVICE
Definition: util-privs.h:33
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:176
#define CLUSTER_FLOW
Definition: source-pfring.h:75
TmEcode(* PktAcqLoop)(ThreadVars *, void *, void *)
Definition: tm-modules.h:54
TmEcode ReceivePfringThreadDeinit(ThreadVars *, void *)
DeInit function closes pd at exit.
char * RunmodeGetActive(void)
Definition: runmodes.c:190
uint16_t vlan_id[2]
Definition: decode.h:434
uint16_t counter_vlan
Definition: decode.h:671
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1143
int SCKernelVersionIsAtLeast(int major, int minor)
#define TM_FLAG_RECEIVE_TM
Definition: tm-modules.h:31
TmEcode(* PktAcqBreakLoop)(ThreadVars *, void *)
Definition: tm-modules.h:57
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:939
void(* DerefFunc)(void *)
Definition: source-pfring.h:53
#define SURICATA_STOP
Definition: suricata.h:95
#define SCMutexUnlock(mut)
void StatsSetUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Sets a value of type double to the local counter.
Definition: counters.c:185
void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
int max_pending_packets
Definition: suricata.c:215
int datalink
Definition: decode.h:579
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
Structure to hold thread specific variables.
Structure to hold thread specific data for all decode modules.
Definition: decode.h:642
#define GET_PKT_DIRECT_DATA(p)
Definition: decode.h:225
void(* RegisterTests)(void)
Definition: tm-modules.h:65
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
#define SCEnter(...)
Definition: util-debug.h:337
struct TmSlot_ * slot_next
Definition: tm-threads.h:72
TmEcode DecodePfring(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *)
This function passes off to link type decoders.
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:163
#define PKT_IGNORE_CHECKSUM
Definition: decode.h:1110
#define PKT_PSEUDO_STREAM_END
Definition: decode.h:1102
#define PFRING_FLAGS_ZERO_COPY
#define CLUSTER_FLOW_5_TUPLE
Definition: source-pfring.h:77
#define SCReturnInt(x)
Definition: util-debug.h:341
LiveDevice * LiveGetDevice(const char *name)
Get a pointer to the device at idx.
Definition: util-device.c:248
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:48
#define PFRING_CONF_FLAGS_CLUSTER
Definition: source-pfring.h:34
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
uint8_t vlan_idx
Definition: decode.h:435
#define SC_CAP_NET_RAW
Definition: util-privs.h:32
void PacketPoolWait(void)
int ChecksumAutoModeCheck(uint32_t thread_count, unsigned int iface_count, unsigned int iface_fail)
Check if the number of invalid checksums indicate checksum offloading in place.
Definition: util-checksum.c:70
const char * name
Definition: tm-modules.h:44
int ignore_checksum
Definition: util-device.h:45
#define SCMalloc(a)
Definition: util-mem.h:174
struct PfringThreadVars_ PfringThreadVars
Structure to hold thread specific variables.
ChecksumValidationMode checksum_mode
Definition: source-pfring.h:51
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:254
int PacketSetData(Packet *p, uint8_t *pktdata, uint32_t pktlen)
Set data for Packet and set length when zeo copy is used.
Definition: decode.c:616
uint8_t version
Definition: decode-gre.h:405
#define SCFree(a)
Definition: util-mem.h:236
#define PKT_IS_TCP(p)
Definition: decode.h:252
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.h:73
VLANHdr * vlanh[2]
Definition: decode.h:541
uint16_t capture_bypassed
uint32_t default_packet_size
Definition: decode.h:627
#define SCMutex
#define SCLogPerf(...)
Definition: util-debug.h:261
#define StatsSyncCountersIfSignalled(tv)
Definition: counters.h:136
#define SCMutexLock(mut)
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
char iface[PFRING_IFACE_NAME_LENGTH]
Definition: source-pfring.h:45
ChecksumValidationMode
Definition: decode.h:40
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:193
void ReceivePfringThreadExitStats(ThreadVars *, void *)
This function prints stats to the screen at exit.
#define GET_PKT_DATA(p)
Definition: decode.h:224
void DecodeUpdatePacketCounters(ThreadVars *tv, const DecodeThreadVars *dtv, const Packet *p)
Definition: decode.c:536
void TmModuleDecodePfringRegister(void)
Registration Function for DecodePfring.
#define SCStrdup(a)
Definition: util-mem.h:220
char name[16]
Definition: threadvars.h:59
#define LINKTYPE_ETHERNET
Definition: decode.h:1081
struct LiveDevice_ * livedev
Definition: decode.h:558
#define PKT_IS_UDP(p)
Definition: decode.h:253
Per thread variable structure.
Definition: threadvars.h:57
struct timeval ts
Definition: decode.h:450
#define GET_PKT_LEN(p)
Definition: decode.h:223
uint32_t flags
Definition: decode.h:442
#define likely(expr)
Definition: util-optimize.h:32
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:596
uint16_t capture_kernel_packets
uint16_t capture_kernel_drops
#define PFRING_FLAGS_BYPASS
void TmModuleReceivePfringRegister(void)
Registration Function for RecievePfring.
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:1251
#define SCMUTEX_INITIALIZER