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