suricata
source-af-packet.c
Go to the documentation of this file.
1 /* Copyright (C) 2011-2021 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \defgroup afppacket AF_PACKET running mode
20  *
21  * @{
22  */
23 
24 /**
25  * \file
26  *
27  * \author Eric Leblond <eric@regit.org>
28  *
29  * AF_PACKET socket acquisition support
30  *
31  */
32 
33 #define PCAP_DONT_INCLUDE_PCAP_BPF_H 1
34 #define SC_PCAP_DONT_INCLUDE_PCAP_H 1
36 #include "suricata.h"
37 #include "packet.h"
38 #include "decode.h"
39 #include "packet-queue.h"
40 #include "threads.h"
41 #include "threadvars.h"
42 #include "tm-queuehandlers.h"
43 #include "tm-modules.h"
44 #include "tm-threads.h"
45 #include "tm-threads-common.h"
46 #include "conf.h"
47 #include "util-cpu.h"
48 #include "util-datalink.h"
49 #include "util-debug.h"
50 #include "util-device.h"
51 #include "util-ebpf.h"
52 #include "util-error.h"
53 #include "util-privs.h"
54 #include "util-optimize.h"
55 #include "util-checksum.h"
56 #include "util-ioctl.h"
57 #include "util-host-info.h"
58 #include "tmqh-packetpool.h"
59 #include "source-af-packet.h"
60 #include "runmodes.h"
61 #include "flow-storage.h"
62 #include "util-validate.h"
63 #include "action-globals.h"
64 
65 #ifdef HAVE_AF_PACKET
66 
67 #if HAVE_SYS_IOCTL_H
68 #include <sys/ioctl.h>
69 #endif
70 
71 #if HAVE_LINUX_SOCKIOS_H
72 #include <linux/sockios.h>
73 #endif
74 
75 #ifdef HAVE_PACKET_EBPF
76 #include <bpf/libbpf.h>
77 #include <bpf/bpf.h>
78 #endif
79 
80 struct bpf_program {
81  unsigned int bf_len;
82  struct bpf_insn *bf_insns;
83 };
84 
85 #ifdef HAVE_PCAP_H
86 #include <pcap.h>
87 #endif
88 
89 #ifdef HAVE_PCAP_PCAP_H
90 #include <pcap/pcap.h>
91 #endif
92 
93 #include "util-bpf.h"
94 
95 #if HAVE_LINUX_IF_ETHER_H
96 #include <linux/if_ether.h>
97 #endif
98 
99 #if HAVE_LINUX_IF_PACKET_H
100 #include <linux/if_packet.h>
101 #endif
102 
103 #if HAVE_LINUX_IF_ARP_H
104 #include <linux/if_arp.h>
105 #endif
106 
107 #if HAVE_LINUX_FILTER_H
108 #include <linux/filter.h>
109 #endif
110 
111 #if HAVE_SYS_MMAN_H
112 #include <sys/mman.h>
113 #endif
114 
115 #ifdef HAVE_HW_TIMESTAMPING
116 #include <linux/net_tstamp.h>
117 #endif
118 
119 #endif /* HAVE_AF_PACKET */
120 
121 extern uint16_t max_pending_packets;
122 
123 #ifndef HAVE_AF_PACKET
124 
125 TmEcode NoAFPSupportExit(ThreadVars *, const void *, void **);
126 
127 void TmModuleReceiveAFPRegister (void)
128 {
129  tmm_modules[TMM_RECEIVEAFP].name = "ReceiveAFP";
130  tmm_modules[TMM_RECEIVEAFP].ThreadInit = NoAFPSupportExit;
136 }
137 
138 /**
139  * \brief Registration Function for DecodeAFP.
140  */
141 void TmModuleDecodeAFPRegister (void)
142 {
143  tmm_modules[TMM_DECODEAFP].name = "DecodeAFP";
144  tmm_modules[TMM_DECODEAFP].ThreadInit = NoAFPSupportExit;
150 }
151 
152 /**
153  * \brief this function prints an error message and exits.
154  */
155 TmEcode NoAFPSupportExit(ThreadVars *tv, const void *initdata, void **data)
156 {
157  SCLogError("Error creating thread %s: you do not have "
158  "support for AF_PACKET enabled, on Linux host please recompile "
159  "with --enable-af-packet",
160  tv->name);
161  exit(EXIT_FAILURE);
162 }
163 
164 #else /* We have AF_PACKET support */
165 
166 #define AFP_IFACE_NAME_LENGTH 48
167 
168 #define AFP_STATE_DOWN 0
169 #define AFP_STATE_UP 1
170 
171 #define AFP_RECONNECT_TIMEOUT 500000
172 #define AFP_DOWN_COUNTER_INTERVAL 40
173 
174 #define POLL_TIMEOUT 100
175 
176 /* kernel flags defined for RX ring tp_status */
177 #ifndef TP_STATUS_KERNEL
178 #define TP_STATUS_KERNEL 0
179 #endif
180 #ifndef TP_STATUS_USER
181 #define TP_STATUS_USER BIT_U32(0)
182 #endif
183 #ifndef TP_STATUS_COPY
184 #define TP_STATUS_COPY BIT_U32(1)
185 #endif
186 #ifndef TP_STATUS_LOSING
187 #define TP_STATUS_LOSING BIT_U32(2)
188 #endif
189 #ifndef TP_STATUS_CSUMNOTREADY
190 #define TP_STATUS_CSUMNOTREADY BIT_U32(3)
191 #endif
192 #ifndef TP_STATUS_VLAN_VALID
193 #define TP_STATUS_VLAN_VALID BIT_U32(4)
194 #endif
195 #ifndef TP_STATUS_BLK_TMO
196 #define TP_STATUS_BLK_TMO BIT_U32(5)
197 #endif
198 #ifndef TP_STATUS_VLAN_TPID_VALID
199 #define TP_STATUS_VLAN_TPID_VALID BIT_U32(6)
200 #endif
201 #ifndef TP_STATUS_CSUM_VALID
202 #define TP_STATUS_CSUM_VALID BIT_U32(7)
203 #endif
204 
205 #ifndef TP_STATUS_TS_SOFTWARE
206 #define TP_STATUS_TS_SOFTWARE BIT_U32(29)
207 #endif
208 #ifndef TP_STATUS_TS_SYS_HARDWARE
209 #define TP_STATUS_TS_SYS_HARDWARE BIT_U32(30) /* kernel comment says: "deprecated, never set" */
210 #endif
211 #ifndef TP_STATUS_TS_RAW_HARDWARE
212 #define TP_STATUS_TS_RAW_HARDWARE BIT_U32(31)
213 #endif
214 
215 #ifndef TP_STATUS_USER_BUSY
216 /* HACK special setting in the tp_status field for frames we are
217  * still working on. This can happen in autofp mode where the
218  * capture thread goes around the ring and finds a frame that still
219  * hasn't been released by a worker thread.
220  *
221  * We use bits 29, 30, 31. 29 and 31 are software and hardware
222  * timestamps. 30 should not be set by the kernel at all. Combined
223  * they should never be set on the rx-ring together.
224  *
225  * The excessive casting is for handling the fact that the kernel
226  * defines almost all of these as int flags, not unsigned ints. */
227 #define TP_STATUS_USER_BUSY \
228  (uint32_t)((uint32_t)TP_STATUS_TS_SOFTWARE | (uint32_t)TP_STATUS_TS_SYS_HARDWARE | \
229  (uint32_t)TP_STATUS_TS_RAW_HARDWARE)
230 #endif
231 #define FRAME_BUSY(tp_status) \
232  (((uint32_t)(tp_status) & (uint32_t)TP_STATUS_USER_BUSY) == (uint32_t)TP_STATUS_USER_BUSY)
233 
234 enum {
237  /** Error during treatment by other functions of Suricata */
240 };
241 
242 enum {
245 };
246 
247 union thdr {
248  struct tpacket2_hdr *h2;
249 #ifdef HAVE_TPACKET_V3
250  struct tpacket3_hdr *h3;
251 #endif
252  void *raw;
253 };
254 
255 #ifdef HAVE_PACKET_EBPF
256 static int AFPBypassCallback(Packet *p);
257 static int AFPXDPBypassCallback(Packet *p);
258 #endif
259 
260 #define MAX_MAPS 32
261 /**
262  * \brief Structure to hold thread specific variables.
263  */
264 typedef struct AFPThreadVars_
265 {
266  union AFPRing {
267  union thdr **v2;
268  struct iovec *v3;
269  } ring;
270 
271  /* counters */
272  uint64_t pkts;
273 
277  /* data link type for the thread */
278  uint32_t datalink;
279 
280 #ifdef HAVE_PACKET_EBPF
281  /* File descriptor of the IPv4 flow bypass table maps */
282  int v4_map_fd;
283  /* File descriptor of the IPv6 flow bypass table maps */
284  int v6_map_fd;
285 #endif
286 
287  unsigned int frame_offset;
288 
290 
291  /* references to packet and drop counters */
294  uint16_t capture_errors;
295  uint16_t afpacket_spin;
302 
303  uint64_t send_errors_logged; /**< snapshot of send errors logged. */
304 
305  /* handle state */
306  uint8_t afp_state;
307  uint8_t copy_mode;
308  unsigned int flags;
309 
310  /* IPS peer */
312 
313  /*
314  * Init related members
315  */
316 
317  /* thread specific socket */
318  int socket;
319 
323  /* socket buffer size */
325  /* Filter */
326  const char *bpf_filter;
327 
328  int promisc;
329 
330  /* bitmask of ignored ssl_pkttypes */
332 
334 
335  uint16_t cluster_id;
337 
338  int threads;
339 
341  struct tpacket_req v2;
342 #ifdef HAVE_TPACKET_V3
343  struct tpacket_req3 v3;
344 #endif
345  } req;
346 
348  /* IPS output iface */
350 
351  /* mmap'ed ring buffer */
352  unsigned int ring_buflen;
353  uint8_t *ring_buf;
354 
355 #ifdef HAVE_PACKET_EBPF
356  uint8_t xdp_mode;
357  int ebpf_lb_fd;
358  int ebpf_filter_fd;
359  struct ebpf_timeout_config ebpf_t_config;
360 #endif
361 
363 
364 static TmEcode ReceiveAFPThreadInit(ThreadVars *, const void *, void **);
365 static void ReceiveAFPThreadExitStats(ThreadVars *, void *);
366 static TmEcode ReceiveAFPThreadDeinit(ThreadVars *, void *);
367 static TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot);
368 
369 static TmEcode DecodeAFPThreadInit(ThreadVars *, const void *, void **);
370 static TmEcode DecodeAFPThreadDeinit(ThreadVars *tv, void *data);
371 static TmEcode DecodeAFP(ThreadVars *, Packet *, void *);
372 
373 static TmEcode AFPSetBPFFilter(AFPThreadVars *ptv);
374 static int AFPGetIfnumByDev(int fd, const char *ifname, int verbose);
375 static int AFPGetDevFlags(int fd, const char *ifname);
376 static int AFPDerefSocket(AFPPeer* peer);
377 static int AFPRefSocket(AFPPeer* peer);
378 
379 
380 /**
381  * \brief Registration Function for RecieveAFP.
382  * \todo Unit tests are needed for this module.
383  */
385 {
386  tmm_modules[TMM_RECEIVEAFP].name = "ReceiveAFP";
387  tmm_modules[TMM_RECEIVEAFP].ThreadInit = ReceiveAFPThreadInit;
389  tmm_modules[TMM_RECEIVEAFP].PktAcqLoop = ReceiveAFPLoop;
391  tmm_modules[TMM_RECEIVEAFP].ThreadExitPrintStats = ReceiveAFPThreadExitStats;
392  tmm_modules[TMM_RECEIVEAFP].ThreadDeinit = ReceiveAFPThreadDeinit;
395 
396 }
397 
398 /**
399  * \defgroup afppeers AFP peers list
400  *
401  * AF_PACKET has an IPS mode were interface are peered: packet from
402  * on interface are sent the peered interface and the other way. The ::AFPPeer
403  * list is maintaining the list of peers. Each ::AFPPeer is storing the needed
404  * information to be able to send packet on the interface.
405  * A element of the list must not be destroyed during the run of Suricata as it
406  * is used by ::Packet and other threads.
407  *
408  * @{
409  */
410 
411 typedef struct AFPPeersList_ {
412  TAILQ_HEAD(, AFPPeer_) peers; /**< Head of list of fragments. */
413  int cnt;
414  int peered;
415  int turn; /**< Next value for initialisation order */
416  SC_ATOMIC_DECLARE(int, reached); /**< Counter used to synchronize start */
418 
419 /**
420  * \brief Update the peer.
421  *
422  * Update the AFPPeer of a thread ie set new state, socket number
423  * or iface index.
424  *
425  */
426 static void AFPPeerUpdate(AFPThreadVars *ptv)
427 {
428  if (ptv->mpeer == NULL) {
429  return;
430  }
431  (void)SC_ATOMIC_SET(ptv->mpeer->if_idx, AFPGetIfnumByDev(ptv->socket, ptv->iface, 0));
432  (void)SC_ATOMIC_SET(ptv->mpeer->socket, ptv->socket);
433  (void)SC_ATOMIC_SET(ptv->mpeer->state, ptv->afp_state);
434 }
435 
436 /**
437  * \brief Clean and free ressource used by an ::AFPPeer
438  */
439 static void AFPPeerClean(AFPPeer *peer)
440 {
441  if (peer->flags & AFP_SOCK_PROTECT)
443  SCFree(peer);
444 }
445 
447 
448 
449 /**
450  * \brief Init the global list of ::AFPPeer
451  */
453 {
454  SCEnter();
455  TAILQ_INIT(&peerslist.peers);
456  peerslist.peered = 0;
457  peerslist.cnt = 0;
458  peerslist.turn = 0;
459  SC_ATOMIC_INIT(peerslist.reached);
460  (void) SC_ATOMIC_SET(peerslist.reached, 0);
462 }
463 
464 /**
465  * \brief Check that all ::AFPPeer got a peer
466  *
467  * \retval TM_ECODE_FAILED if some threads are not peered or TM_ECODE_OK else.
468  */
470 {
471 #define AFP_PEERS_MAX_TRY 4
472 #define AFP_PEERS_WAIT 20000
473  int try = 0;
474  SCEnter();
475  while (try < AFP_PEERS_MAX_TRY) {
476  if (peerslist.cnt != peerslist.peered) {
477  usleep(AFP_PEERS_WAIT);
478  } else {
480  }
481  try++;
482  }
483  SCLogError("thread number not equal");
485 }
486 
487 /**
488  * \brief Declare a new AFP thread to AFP peers list.
489  */
490 static TmEcode AFPPeersListAdd(AFPThreadVars *ptv)
491 {
492  SCEnter();
493  AFPPeer *peer = SCMalloc(sizeof(AFPPeer));
494  AFPPeer *pitem;
495 
496  if (unlikely(peer == NULL)) {
498  }
499  memset(peer, 0, sizeof(AFPPeer));
500  SC_ATOMIC_INIT(peer->socket);
501  SC_ATOMIC_INIT(peer->sock_usage);
502  SC_ATOMIC_INIT(peer->if_idx);
503  SC_ATOMIC_INIT(peer->state);
504  peer->flags = ptv->flags;
505  peer->turn = peerslist.turn++;
506 
507  if (peer->flags & AFP_SOCK_PROTECT) {
508  SCMutexInit(&peer->sock_protect, NULL);
509  }
510 
511  (void)SC_ATOMIC_SET(peer->sock_usage, 0);
512  (void)SC_ATOMIC_SET(peer->state, AFP_STATE_DOWN);
514  ptv->mpeer = peer;
515  /* add element to iface list */
516  TAILQ_INSERT_TAIL(&peerslist.peers, peer, next);
517 
518  if (ptv->copy_mode != AFP_COPY_MODE_NONE) {
519  peerslist.cnt++;
520 
521  /* Iter to find a peer */
522  TAILQ_FOREACH(pitem, &peerslist.peers, next) {
523  if (pitem->peer)
524  continue;
525  if (strcmp(pitem->iface, ptv->out_iface))
526  continue;
527  peer->peer = pitem;
528  pitem->peer = peer;
529 
530  LiveDevice *iface = ptv->livedev;
531  DEBUG_VALIDATE_BUG_ON(iface == NULL);
532  DEBUG_VALIDATE_BUG_ON(strcmp(iface->dev, ptv->iface) != 0);
533  LiveDevice *out_iface = LiveGetDevice(ptv->out_iface);
534  if (out_iface == NULL)
535  FatalError("AF_PACKET device %s not found. Aborting..", ptv->out_iface);
536  if (iface->mtu != out_iface->mtu) {
537  SCLogWarning("MTU on %s (%d) and %s (%d) are not equal, transmission of packets "
538  "bigger than %d will fail.",
539  iface->dev, iface->mtu, out_iface->dev, out_iface->mtu,
540  MIN(out_iface->mtu, iface->mtu));
541  }
542  peerslist.peered += 2;
543  break;
544  }
545  }
546 
547  AFPPeerUpdate(ptv);
548 
550 }
551 
552 static int AFPPeersListWaitTurn(AFPPeer *peer)
553 {
554  /* If turn is zero, we already have started threads once */
555  if (peerslist.turn == 0)
556  return 0;
557 
558  if (peer->turn == SC_ATOMIC_GET(peerslist.reached))
559  return 0;
560  return 1;
561 }
562 
563 static void AFPPeersListReachedInc(void)
564 {
565  if (peerslist.turn == 0)
566  return;
567 
568  if ((SC_ATOMIC_ADD(peerslist.reached, 1) + 1) == peerslist.turn) {
569  (void)SC_ATOMIC_SET(peerslist.reached, 0);
570  /* Set turn to 0 to skip synchronization when ReceiveAFPLoop is
571  * restarted.
572  */
573  peerslist.turn = 0;
574  }
575 }
576 
577 static int AFPPeersListStarted(void)
578 {
579  return !peerslist.turn;
580 }
581 
582 /**
583  * \brief Clean the global peers list.
584  */
586 {
587  AFPPeer *pitem;
588 
589  while ((pitem = TAILQ_FIRST(&peerslist.peers))) {
590  TAILQ_REMOVE(&peerslist.peers, pitem, next);
591  AFPPeerClean(pitem);
592  }
593 }
594 
595 /**
596  * @}
597  */
598 
599 /**
600  * \brief Registration Function for DecodeAFP.
601  * \todo Unit tests are needed for this module.
602  */
604 {
605  tmm_modules[TMM_DECODEAFP].name = "DecodeAFP";
606  tmm_modules[TMM_DECODEAFP].ThreadInit = DecodeAFPThreadInit;
607  tmm_modules[TMM_DECODEAFP].Func = DecodeAFP;
609  tmm_modules[TMM_DECODEAFP].ThreadDeinit = DecodeAFPThreadDeinit;
612 }
613 
614 
615 static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose);
616 
617 static inline void AFPDumpCounters(AFPThreadVars *ptv)
618 {
619 #ifdef PACKET_STATISTICS
620  struct tpacket_stats kstats;
621  socklen_t len = sizeof (struct tpacket_stats);
622  if (getsockopt(ptv->socket, SOL_PACKET, PACKET_STATISTICS,
623  &kstats, &len) > -1) {
624  SCLogDebug("(%s) Kernel: Packets %" PRIu32 ", dropped %" PRIu32 "",
625  ptv->tv->name,
626  kstats.tp_packets, kstats.tp_drops);
627  StatsAddUI64(ptv->tv, ptv->capture_kernel_packets, kstats.tp_packets);
628  StatsAddUI64(ptv->tv, ptv->capture_kernel_drops, kstats.tp_drops);
629  (void) SC_ATOMIC_ADD(ptv->livedev->drop, (uint64_t) kstats.tp_drops);
630  (void) SC_ATOMIC_ADD(ptv->livedev->pkts, (uint64_t) kstats.tp_packets);
631 
632  const uint64_t value = SC_ATOMIC_GET(ptv->mpeer->send_errors);
633  if (value > ptv->send_errors_logged) {
634  StatsAddUI64(ptv->tv, ptv->capture_afp_send_err, value - ptv->send_errors_logged);
635  ptv->send_errors_logged = value;
636  }
637  }
638 #endif
639 }
640 
641 /**
642  * \brief AF packet write function.
643  *
644  * This function has to be called before the memory
645  * related to Packet in ring buffer is released.
646  *
647  * \param pointer to Packet
648  * \param version of capture: TPACKET_V2 or TPACKET_V3
649  * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
650  *
651  */
652 static void AFPWritePacket(Packet *p, int version)
653 {
654  struct sockaddr_ll socket_address;
655  int socket;
656 
657  if (p->afp_v.copy_mode == AFP_COPY_MODE_IPS) {
658  if (PacketCheckAction(p, ACTION_DROP)) {
659  return;
660  }
661  }
662 
663  if (p->ethh == NULL) {
664  SCLogWarning("packet should have an ethernet header");
665  return;
666  }
667 
668  /* Index of the network device */
669  socket_address.sll_ifindex = SC_ATOMIC_GET(p->afp_v.peer->if_idx);
670  /* Address length*/
671  socket_address.sll_halen = ETH_ALEN;
672  /* Destination MAC */
673  memcpy(socket_address.sll_addr, p->ethh, 6);
674 
675  /* Send packet, locking the socket if necessary */
676  if (p->afp_v.peer->flags & AFP_SOCK_PROTECT)
677  SCMutexLock(&p->afp_v.peer->sock_protect);
678  socket = SC_ATOMIC_GET(p->afp_v.peer->socket);
679 
680  if (sendto(socket, GET_PKT_DATA(p), GET_PKT_LEN(p), 0, (struct sockaddr *)&socket_address,
681  sizeof(struct sockaddr_ll)) < 0) {
682  if (SC_ATOMIC_ADD(p->afp_v.peer->send_errors, 1) == 0) {
683  SCLogWarning("%s: sending packet failed on socket %d: %s", p->afp_v.peer->iface, socket,
684  strerror(errno));
685  }
686  }
687  if (p->afp_v.peer->flags & AFP_SOCK_PROTECT)
688  SCMutexUnlock(&p->afp_v.peer->sock_protect);
689 }
690 
691 static void AFPReleaseDataFromRing(Packet *p)
692 {
694 
695  /* Need to be in copy mode and need to detect early release
696  where Ethernet header could not be set (and pseudo packet) */
697  if (p->afp_v.copy_mode != AFP_COPY_MODE_NONE) {
698  AFPWritePacket(p, TPACKET_V2);
699  }
700 
701  BUG_ON(p->afp_v.relptr == NULL);
702 
703  union thdr h;
704  h.raw = p->afp_v.relptr;
705  h.h2->tp_status = TP_STATUS_KERNEL;
706 
707  (void)AFPDerefSocket(p->afp_v.mpeer);
708 
709  AFPV_CLEANUP(&p->afp_v);
710 }
711 
712 #ifdef HAVE_TPACKET_V3
713 static void AFPReleasePacketV3(Packet *p)
714 {
716 
717  /* Need to be in copy mode and need to detect early release
718  where Ethernet header could not be set (and pseudo packet) */
719  if (p->afp_v.copy_mode != AFP_COPY_MODE_NONE) {
720  AFPWritePacket(p, TPACKET_V3);
721  }
723 }
724 #endif
725 
726 static void AFPReleasePacket(Packet *p)
727 {
728  AFPReleaseDataFromRing(p);
730 }
731 
732 /** \internal
733  * \brief recoverable error - release packet and
734  * return AFP_SURI_FAILURE
735  */
736 static inline int AFPSuriFailure(AFPThreadVars *ptv, union thdr h)
737 {
738  h.h2->tp_status = TP_STATUS_KERNEL;
739  if (++ptv->frame_offset >= ptv->req.v2.tp_frame_nr) {
740  ptv->frame_offset = 0;
741  }
743 }
744 
745 static inline void AFPReadApplyBypass(const AFPThreadVars *ptv, Packet *p)
746 {
747 #ifdef HAVE_PACKET_EBPF
748  if (ptv->flags & AFP_BYPASS) {
749  p->BypassPacketsFlow = AFPBypassCallback;
750  p->afp_v.v4_map_fd = ptv->v4_map_fd;
751  p->afp_v.v6_map_fd = ptv->v6_map_fd;
752  p->afp_v.nr_cpus = ptv->ebpf_t_config.cpus_count;
753  }
754  if (ptv->flags & AFP_XDPBYPASS) {
755  p->BypassPacketsFlow = AFPXDPBypassCallback;
756  p->afp_v.v4_map_fd = ptv->v4_map_fd;
757  p->afp_v.v6_map_fd = ptv->v6_map_fd;
758  p->afp_v.nr_cpus = ptv->ebpf_t_config.cpus_count;
759  }
760 #endif
761 }
762 
763 /** \internal
764  * \brief setup packet for AFPReadFromRing
765  */
766 static void AFPReadFromRingSetupPacket(
767  AFPThreadVars *ptv, union thdr h, const unsigned int tp_status, Packet *p)
768 {
770 
771  /* flag the packet as TP_STATUS_USER_BUSY, which is ignore by the kernel, but
772  * acts as an indicator that we've reached a frame that is not yet released by
773  * us in autofp mode. It will be cleared when the frame gets released to the kernel. */
774  h.h2->tp_status |= TP_STATUS_USER_BUSY;
775  p->livedev = ptv->livedev;
776  p->datalink = ptv->datalink;
777  ptv->pkts++;
778 
779  AFPReadApplyBypass(ptv, p);
780 
781  if (h.h2->tp_len > h.h2->tp_snaplen) {
782  SCLogDebug("Packet length (%d) > snaplen (%d), truncating", h.h2->tp_len, h.h2->tp_snaplen);
783  }
784 
785  /* get vlan id from header */
786  if ((ptv->flags & AFP_VLAN_IN_HEADER) &&
787  (tp_status & TP_STATUS_VLAN_VALID || h.h2->tp_vlan_tci)) {
788  p->vlan_id[0] = h.h2->tp_vlan_tci & 0x0fff;
789  p->vlan_idx = 1;
790  p->afp_v.vlan_tci = h.h2->tp_vlan_tci;
791  }
792 
793  (void)PacketSetData(p, (unsigned char *)h.raw + h.h2->tp_mac, h.h2->tp_snaplen);
794 
795  p->ReleasePacket = AFPReleasePacket;
796  p->afp_v.relptr = h.raw;
797  if (ptv->flags & AFP_NEED_PEER) {
798  p->afp_v.mpeer = ptv->mpeer;
799  AFPRefSocket(ptv->mpeer);
800  } else {
801  p->afp_v.mpeer = NULL;
802  }
803  p->afp_v.copy_mode = ptv->copy_mode;
804  p->afp_v.peer = (p->afp_v.copy_mode == AFP_COPY_MODE_NONE) ? NULL : ptv->mpeer->peer;
805 
806  /* Timestamp */
807  p->ts = (SCTime_t){ .secs = h.h2->tp_sec, .usecs = h.h2->tp_nsec / 1000 };
808  SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)", GET_PKT_LEN(p), p, GET_PKT_DATA(p));
809 
810  /* We only check for checksum disable */
813  } else if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) {
814  if (ChecksumAutoModeCheck(ptv->pkts, SC_ATOMIC_GET(ptv->livedev->pkts),
815  SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
818  }
819  } else {
820  if (tp_status & TP_STATUS_CSUMNOTREADY) {
822  }
823  }
824 }
825 
826 static inline int AFPReadFromRingWaitForPacket(AFPThreadVars *ptv)
827 {
828  union thdr h;
829  struct timeval start_time;
830  gettimeofday(&start_time, NULL);
831  uint64_t busy_loop_iter = 0;
832 
833  /* busy wait loop until we have packets available */
834  while (1) {
835  if (unlikely(suricata_ctl_flags != 0)) {
836  break;
837  }
838  h.raw = (((union thdr **)ptv->ring.v2)[ptv->frame_offset]);
839  if (unlikely(h.raw == NULL)) {
840  return AFP_READ_FAILURE;
841  }
842  const unsigned int tp_status = h.h2->tp_status;
843  if (tp_status == TP_STATUS_KERNEL) {
844  busy_loop_iter++;
845 
846  struct timeval cur_time;
847  memset(&cur_time, 0, sizeof(cur_time));
848  uint64_t milliseconds =
849  ((cur_time.tv_sec - start_time.tv_sec) * 1000) +
850  (((1000000 + cur_time.tv_usec - start_time.tv_usec) / 1000) - 1000);
851  if (milliseconds > 1000) {
852  break;
853  }
854  continue;
855  }
856  break;
857  }
858  if (busy_loop_iter) {
859  StatsAddUI64(ptv->tv, ptv->afpacket_spin, busy_loop_iter);
860  }
861  return AFP_READ_OK;
862 }
863 
864 /**
865  * \brief AF packet frame ignore logic
866  *
867  * Given a sockaddr_ll of a frame, use the pkttype_filter_mask to decide if the
868  * frame should be ignored. Protect from undefined behavior if there's ever
869  * a sll_pkttype that would shift by too much. At this point, only outgoing
870  * packets (4) are ignored. The highest value in if_linux.h is PACKET_KERNEL (7),
871  * this extra check is being overly cautious.
872  *
873  * \retval true if the frame should be ignored
874  */
875 static inline bool AFPShouldIgnoreFrame(AFPThreadVars *ptv, const struct sockaddr_ll *sll)
876 {
877  if (unlikely(sll->sll_pkttype > 31))
878  return false;
879 
880  return (ptv->pkttype_filter_mask & BIT_U32(sll->sll_pkttype)) != 0;
881 }
882 
883 /**
884  * \brief AF packet read function for ring
885  *
886  * This function fills
887  * From here the packets are picked up by the DecodeAFP thread.
888  *
889  * \param user pointer to AFPThreadVars
890  * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
891  */
892 static int AFPReadFromRing(AFPThreadVars *ptv)
893 {
894  union thdr h;
895  bool emergency_flush = false;
896  const unsigned int start_pos = ptv->frame_offset;
897 
898  /* poll() told us there are frames, so lets wait for at least
899  * one frame to become available. */
900  if (AFPReadFromRingWaitForPacket(ptv) != AFP_READ_OK)
901  return AFP_READ_FAILURE;
902 
903  /* process the frames in the ring */
904  while (1) {
905  if (unlikely(suricata_ctl_flags != 0)) {
906  break;
907  }
908  h.raw = (((union thdr **)ptv->ring.v2)[ptv->frame_offset]);
909  if (unlikely(h.raw == NULL)) {
910  return AFP_READ_FAILURE;
911  }
912  const unsigned int tp_status = h.h2->tp_status;
913  /* if we find a kernel frame we are done */
914  if (unlikely(tp_status == TP_STATUS_KERNEL)) {
915  break;
916  }
917  /* if in autofp mode the frame is still busy, return to poll */
918  if (unlikely(FRAME_BUSY(tp_status))) {
919  break;
920  }
921  emergency_flush |= ((tp_status & TP_STATUS_LOSING) != 0);
922 
923  if ((ptv->flags & AFP_EMERGENCY_MODE) && emergency_flush) {
924  h.h2->tp_status = TP_STATUS_KERNEL;
925  goto next_frame;
926  }
927 
928  const struct sockaddr_ll *sll =
929  (const struct sockaddr_ll *)((uint8_t *)h.h2 +
930  TPACKET_ALIGN(sizeof(struct tpacket2_hdr)));
931  if (unlikely(AFPShouldIgnoreFrame(ptv, sll)))
932  goto next_frame;
933 
935  if (p == NULL) {
936  return AFPSuriFailure(ptv, h);
937  }
938  AFPReadFromRingSetupPacket(ptv, h, tp_status, p);
939 
940  if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
941  return AFPSuriFailure(ptv, h);
942  }
943 next_frame:
944  if (++ptv->frame_offset >= ptv->req.v2.tp_frame_nr) {
945  ptv->frame_offset = 0;
946  /* Get out of loop to be sure we will reach maintenance tasks */
947  if (ptv->frame_offset == start_pos)
948  break;
949  }
950  }
951  if (emergency_flush) {
952  AFPDumpCounters(ptv);
953  }
955 }
956 
957 #ifdef HAVE_TPACKET_V3
958 static inline void AFPFlushBlock(struct tpacket_block_desc *pbd)
959 {
960  pbd->hdr.bh1.block_status = TP_STATUS_KERNEL;
961 }
962 
963 static inline int AFPParsePacketV3(AFPThreadVars *ptv, struct tpacket_block_desc *pbd, struct tpacket3_hdr *ppd)
964 {
966  if (p == NULL) {
968  }
970 
971  AFPReadApplyBypass(ptv, p);
972 
973  ptv->pkts++;
974  p->livedev = ptv->livedev;
975  p->datalink = ptv->datalink;
976 
977  if ((ptv->flags & AFP_VLAN_IN_HEADER) &&
978  (ppd->tp_status & TP_STATUS_VLAN_VALID || ppd->hv1.tp_vlan_tci)) {
979  p->vlan_id[0] = ppd->hv1.tp_vlan_tci & 0x0fff;
980  p->vlan_idx = 1;
981  p->afp_v.vlan_tci = (uint16_t)ppd->hv1.tp_vlan_tci;
982  }
983 
984  (void)PacketSetData(p, (unsigned char *)ppd + ppd->tp_mac, ppd->tp_snaplen);
985 
986  p->ReleasePacket = AFPReleasePacketV3;
987  p->afp_v.relptr = NULL;
988  p->afp_v.mpeer = NULL;
989  p->afp_v.copy_mode = ptv->copy_mode;
990  p->afp_v.peer = (p->afp_v.copy_mode == AFP_COPY_MODE_NONE) ? NULL : ptv->mpeer->peer;
991 
992  /* Timestamp */
993  p->ts = (SCTime_t){ .secs = ppd->tp_sec, .usecs = ppd->tp_nsec / 1000 };
994  SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)",
995  GET_PKT_LEN(p), p, GET_PKT_DATA(p));
996 
997  /* We only check for checksum disable */
1000  } else if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) {
1001  if (ChecksumAutoModeCheck(ptv->pkts,
1002  SC_ATOMIC_GET(ptv->livedev->pkts),
1003  SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
1005  p->flags |= PKT_IGNORE_CHECKSUM;
1006  }
1007  } else {
1008  if (ppd->tp_status & TP_STATUS_CSUMNOTREADY) {
1009  p->flags |= PKT_IGNORE_CHECKSUM;
1010  }
1011  }
1012 
1013  if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
1015  }
1016 
1018 }
1019 
1020 static inline int AFPWalkBlock(AFPThreadVars *ptv, struct tpacket_block_desc *pbd)
1021 {
1022  const int num_pkts = pbd->hdr.bh1.num_pkts;
1023  uint8_t *ppd = (uint8_t *)pbd + pbd->hdr.bh1.offset_to_first_pkt;
1024 
1025  for (int i = 0; i < num_pkts; ++i) {
1026  const struct sockaddr_ll *sll =
1027  (const struct sockaddr_ll *)(ppd + TPACKET_ALIGN(sizeof(struct tpacket3_hdr)));
1028  if (unlikely(AFPShouldIgnoreFrame(ptv, sll))) {
1029  ppd = ppd + ((struct tpacket3_hdr *)ppd)->tp_next_offset;
1030  continue;
1031  }
1032  int ret = AFPParsePacketV3(ptv, pbd, (struct tpacket3_hdr *)ppd);
1033  switch (ret) {
1034  case AFP_READ_OK:
1035  break;
1036  case AFP_SURI_FAILURE:
1037  /* Internal error but let's just continue and
1038  * treat thenext packet */
1039  break;
1040  case AFP_READ_FAILURE:
1042  default:
1043  SCReturnInt(ret);
1044  }
1045  ppd = ppd + ((struct tpacket3_hdr *)ppd)->tp_next_offset;
1046  }
1047 
1049 }
1050 #endif /* HAVE_TPACKET_V3 */
1051 
1052 /**
1053  * \brief AF packet read function for ring
1054  *
1055  * This function fills
1056  * From here the packets are picked up by the DecodeAFP thread.
1057  *
1058  * \param user pointer to AFPThreadVars
1059  * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
1060  */
1061 static int AFPReadFromRingV3(AFPThreadVars *ptv)
1062 {
1063 #ifdef HAVE_TPACKET_V3
1064  /* Loop till we have packets available */
1065  while (1) {
1066  if (unlikely(suricata_ctl_flags != 0)) {
1067  SCLogDebug("Exiting AFP V3 read loop");
1068  break;
1069  }
1070 
1071  struct tpacket_block_desc *pbd =
1072  (struct tpacket_block_desc *)ptv->ring.v3[ptv->frame_offset].iov_base;
1073 
1074  /* block is not ready to be read */
1075  if ((pbd->hdr.bh1.block_status & TP_STATUS_USER) == 0) {
1077  }
1078 
1079  int ret = AFPWalkBlock(ptv, pbd);
1080  if (unlikely(ret != AFP_READ_OK)) {
1081  AFPFlushBlock(pbd);
1082  SCReturnInt(ret);
1083  }
1084 
1085  AFPFlushBlock(pbd);
1086  ptv->frame_offset = (ptv->frame_offset + 1) % ptv->req.v3.tp_block_nr;
1087  /* return to maintenance task after one loop on the ring */
1088  if (ptv->frame_offset == 0) {
1090  }
1091  }
1092 #endif
1094 }
1095 
1096 /**
1097  * \brief Reference socket
1098  *
1099  * \retval O in case of failure, 1 in case of success
1100  */
1101 static int AFPRefSocket(AFPPeer* peer)
1102 {
1103  if (unlikely(peer == NULL))
1104  return 0;
1105 
1106  (void)SC_ATOMIC_ADD(peer->sock_usage, 1);
1107  return 1;
1108 }
1109 
1110 
1111 /**
1112  * \brief Dereference socket
1113  *
1114  * \retval 1 if socket is still alive, 0 if not
1115  */
1116 static int AFPDerefSocket(AFPPeer* peer)
1117 {
1118  if (peer == NULL)
1119  return 1;
1120 
1121  if (SC_ATOMIC_SUB(peer->sock_usage, 1) == 1) {
1122  return 0;
1123  }
1124  return 1;
1125 }
1126 
1127 static void AFPCloseSocket(AFPThreadVars *ptv)
1128 {
1129  if (ptv->mpeer != NULL)
1130  BUG_ON(SC_ATOMIC_GET(ptv->mpeer->sock_usage) != 0);
1131 
1132  if (ptv->flags & AFP_TPACKET_V3) {
1133 #ifdef HAVE_TPACKET_V3
1134  if (ptv->ring.v3) {
1135  SCFree(ptv->ring.v3);
1136  ptv->ring.v3 = NULL;
1137  }
1138 #endif
1139  } else {
1140  if (ptv->ring.v2) {
1141  /* only used in reading phase, we can free it */
1142  SCFree(ptv->ring.v2);
1143  ptv->ring.v2 = NULL;
1144  }
1145  }
1146  if (ptv->socket != -1) {
1147  SCLogDebug("Cleaning socket connected to '%s'", ptv->iface);
1148  munmap(ptv->ring_buf, ptv->ring_buflen);
1149  close(ptv->socket);
1150  ptv->socket = -1;
1151  }
1152 }
1153 
1154 static void AFPSwitchState(AFPThreadVars *ptv, uint8_t state)
1155 {
1156  ptv->afp_state = state;
1157  ptv->down_count = 0;
1158 
1159  if (state == AFP_STATE_DOWN) {
1160  /* cleanup is done on thread cleanup or try reopen
1161  * as there may still be packets in autofp that
1162  * are referencing us */
1163  (void)SC_ATOMIC_SUB(ptv->mpeer->sock_usage, 1);
1164  }
1165  if (state == AFP_STATE_UP) {
1166  AFPPeerUpdate(ptv);
1167  (void)SC_ATOMIC_SET(ptv->mpeer->sock_usage, 1);
1168  }
1169 }
1170 
1171 static int AFPReadAndDiscardFromRing(AFPThreadVars *ptv, struct timeval *synctv,
1172  uint64_t *discarded_pkts)
1173 {
1174  if (unlikely(suricata_ctl_flags != 0)) {
1175  return 1;
1176  }
1177 
1178 #ifdef HAVE_TPACKET_V3
1179  if (ptv->flags & AFP_TPACKET_V3) {
1180  int ret = 0;
1181  struct tpacket_block_desc *pbd =
1182  (struct tpacket_block_desc *)ptv->ring.v3[ptv->frame_offset].iov_base;
1183  *discarded_pkts += pbd->hdr.bh1.num_pkts;
1184  struct tpacket3_hdr *ppd =
1185  (struct tpacket3_hdr *)((uint8_t *)pbd + pbd->hdr.bh1.offset_to_first_pkt);
1186  if (((time_t)ppd->tp_sec > synctv->tv_sec) ||
1187  ((time_t)ppd->tp_sec == synctv->tv_sec &&
1188  (suseconds_t) (ppd->tp_nsec / 1000) > (suseconds_t)synctv->tv_usec)) {
1189  ret = 1;
1190  }
1191  AFPFlushBlock(pbd);
1192  ptv->frame_offset = (ptv->frame_offset + 1) % ptv->req.v3.tp_block_nr;
1193  return ret;
1194 
1195  } else
1196 #endif
1197  {
1198  /* Read packet from ring */
1199  union thdr h;
1200  h.raw = (((union thdr **)ptv->ring.v2)[ptv->frame_offset]);
1201  if (h.raw == NULL) {
1202  return -1;
1203  }
1204  if (h.h2->tp_status == TP_STATUS_KERNEL)
1205  return 0;
1206 
1207  if (((time_t)h.h2->tp_sec > synctv->tv_sec) ||
1208  ((time_t)h.h2->tp_sec == synctv->tv_sec &&
1209  (suseconds_t) (h.h2->tp_nsec / 1000) > synctv->tv_usec)) {
1210  return 1;
1211  }
1212 
1213  (*discarded_pkts)++;
1214  h.h2->tp_status = TP_STATUS_KERNEL;
1215  if (++ptv->frame_offset >= ptv->req.v2.tp_frame_nr) {
1216  ptv->frame_offset = 0;
1217  }
1218  }
1219 
1220  return 0;
1221 }
1222 
1223 /** \brief wait for all afpacket threads to fully init
1224  *
1225  * Discard packets before all threads are ready, as the cluster
1226  * setup is not complete yet.
1227  *
1228  * if AFPPeersListStarted() returns true init is complete
1229  *
1230  * \retval r 1 = happy, otherwise unhappy
1231  */
1232 static int AFPSynchronizeStart(AFPThreadVars *ptv, uint64_t *discarded_pkts)
1233 {
1234  struct timeval synctv;
1235  struct pollfd fds;
1236 
1237  fds.fd = ptv->socket;
1238  fds.events = POLLIN;
1239 
1240  /* Set timeval to end of the world */
1241  synctv.tv_sec = 0xffffffff;
1242  synctv.tv_usec = 0xffffffff;
1243 
1244  while (1) {
1245  int r = poll(&fds, 1, POLL_TIMEOUT);
1246  if (r > 0 &&
1247  (fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) {
1248  SCLogWarning("%s: poll failed %02x", ptv->iface,
1249  fds.revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL));
1250  return 0;
1251  } else if (r > 0) {
1252  if (AFPPeersListStarted() && synctv.tv_sec == (time_t) 0xffffffff) {
1253  gettimeofday(&synctv, NULL);
1254  }
1255  r = AFPReadAndDiscardFromRing(ptv, &synctv, discarded_pkts);
1256  SCLogDebug("Discarding on %s", ptv->tv->name);
1257  switch (r) {
1258  case 1:
1259  SCLogDebug("Starting to read on %s", ptv->tv->name);
1260  return 1;
1261  case -1:
1262  return r;
1263  }
1264  /* no packets */
1265  } else if (r == 0 && AFPPeersListStarted()) {
1266  SCLogDebug("Starting to read on %s", ptv->tv->name);
1267  return 1;
1268  } else if (r < 0) { /* only exit on error */
1269  SCLogWarning("poll failed with retval %d", r);
1270  return 0;
1271  }
1272  }
1273  return 1;
1274 }
1275 
1276 /**
1277  * \brief Try to reopen socket
1278  *
1279  * \retval 0 in case of success, negative if error occurs or a condition
1280  * is not met.
1281  */
1282 static int AFPTryReopen(AFPThreadVars *ptv)
1283 {
1284  ptv->down_count++;
1285 
1286  /* Don't reconnect till we have packet that did not release data */
1287  if (SC_ATOMIC_GET(ptv->mpeer->sock_usage) != 0) {
1288  return -1;
1289  }
1290 
1291  /* ref cnt 0, we can close the old socket */
1292  AFPCloseSocket(ptv);
1293 
1294  int afp_activate_r = AFPCreateSocket(ptv, ptv->iface, 0);
1295  if (afp_activate_r != 0) {
1296  if (ptv->down_count % AFP_DOWN_COUNTER_INTERVAL == 0) {
1297  SCLogWarning("%s: can't reopen interface", ptv->iface);
1298  }
1299  return afp_activate_r;
1300  }
1301 
1302  SCLogInfo("%s: interface is back up", ptv->iface);
1303  return 0;
1304 }
1305 
1306 /**
1307  * \brief Main AF_PACKET reading Loop function
1308  */
1309 TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot)
1310 {
1311  SCEnter();
1312 
1313  AFPThreadVars *ptv = (AFPThreadVars *)data;
1314  struct pollfd fds;
1315  int r;
1316  TmSlot *s = (TmSlot *)slot;
1317  time_t last_dump = 0;
1318  time_t current_time;
1319  int (*AFPReadFunc) (AFPThreadVars *);
1320  uint64_t discarded_pkts = 0;
1321 
1322  ptv->slot = s->slot_next;
1323 
1324  if (ptv->flags & AFP_TPACKET_V3) {
1325  AFPReadFunc = AFPReadFromRingV3;
1326  } else {
1327  AFPReadFunc = AFPReadFromRing;
1328  }
1329 
1330  if (ptv->afp_state == AFP_STATE_DOWN) {
1331  /* Wait for our turn, threads before us must have opened the socket */
1332  while (AFPPeersListWaitTurn(ptv->mpeer)) {
1333  usleep(1000);
1334  if (suricata_ctl_flags != 0) {
1335  break;
1336  }
1337  }
1338  r = AFPCreateSocket(ptv, ptv->iface, 1);
1339  if (r < 0) {
1340  switch (-r) {
1341  case AFP_FATAL_ERROR:
1342  SCLogError("%s: failed to init socket for interface", ptv->iface);
1344  case AFP_RECOVERABLE_ERROR:
1345  SCLogWarning(
1346  "%s: failed to init socket for interface, retrying soon", ptv->iface);
1347  }
1348  }
1349  AFPPeersListReachedInc();
1350  }
1351  if (ptv->afp_state == AFP_STATE_UP) {
1352  SCLogDebug("Thread %s using socket %d", tv->name, ptv->socket);
1353  AFPSynchronizeStart(ptv, &discarded_pkts);
1354  /* let's reset counter as we will start the capture at the
1355  * next function call */
1356 #ifdef PACKET_STATISTICS
1357  struct tpacket_stats kstats;
1358  socklen_t len = sizeof (struct tpacket_stats);
1359  if (getsockopt(ptv->socket, SOL_PACKET, PACKET_STATISTICS,
1360  &kstats, &len) > -1) {
1361  uint64_t pkts = 0;
1362  SCLogDebug("(%s) Kernel socket startup: Packets %" PRIu32
1363  ", dropped %" PRIu32 "",
1364  ptv->tv->name,
1365  kstats.tp_packets, kstats.tp_drops);
1366  pkts = kstats.tp_packets - discarded_pkts - kstats.tp_drops;
1367  StatsAddUI64(ptv->tv, ptv->capture_kernel_packets, pkts);
1368  (void) SC_ATOMIC_ADD(ptv->livedev->pkts, pkts);
1369  }
1370 #endif
1371  }
1372 
1373  fds.fd = ptv->socket;
1374  fds.events = POLLIN;
1375 
1376  // Indicate that the thread is actually running its application level code (i.e., it can poll
1377  // packets)
1379 
1380  while (1) {
1381  /* Start by checking the state of our interface */
1382  if (unlikely(ptv->afp_state == AFP_STATE_DOWN)) {
1383  int dbreak = 0;
1384 
1385  do {
1386  usleep(AFP_RECONNECT_TIMEOUT);
1387  if (suricata_ctl_flags != 0) {
1388  dbreak = 1;
1389  break;
1390  }
1391  r = AFPTryReopen(ptv);
1392  fds.fd = ptv->socket;
1393  } while (r < 0);
1394  if (dbreak == 1)
1395  break;
1396  }
1397 
1398  /* make sure we have at least one packet in the packet pool, to prevent
1399  * us from alloc'ing packets at line rate */
1400  PacketPoolWait();
1401 
1402  StatsIncr(ptv->tv, ptv->capture_afp_poll);
1403 
1404  r = poll(&fds, 1, POLL_TIMEOUT);
1405 
1406  if (suricata_ctl_flags != 0) {
1407  break;
1408  }
1409 
1410  if (r > 0 &&
1411  (fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) {
1412  StatsIncr(ptv->tv, ptv->capture_afp_poll_signal);
1413  if (fds.revents & (POLLHUP | POLLRDHUP)) {
1414  AFPSwitchState(ptv, AFP_STATE_DOWN);
1415  continue;
1416  } else if (fds.revents & POLLERR) {
1417  char c;
1418  /* Do a recv to get errno */
1419  if (recv(ptv->socket, &c, sizeof c, MSG_PEEK) != -1)
1420  continue; /* what, no error? */
1421  SCLogWarning("%s: failed to poll interface: %s", ptv->iface, strerror(errno));
1422  AFPSwitchState(ptv, AFP_STATE_DOWN);
1423  continue;
1424  } else if (fds.revents & POLLNVAL) {
1425  SCLogWarning("%s: invalid poll request: %s", ptv->iface, strerror(errno));
1426  AFPSwitchState(ptv, AFP_STATE_DOWN);
1427  continue;
1428  }
1429  } else if (r > 0) {
1430  StatsIncr(ptv->tv, ptv->capture_afp_poll_data);
1431  r = AFPReadFunc(ptv);
1432  switch (r) {
1433  case AFP_READ_OK:
1434  /* Trigger one dump of stats every second */
1435  current_time = time(NULL);
1436  if (current_time != last_dump) {
1437  AFPDumpCounters(ptv);
1438  last_dump = current_time;
1439  }
1440  break;
1441  case AFP_READ_FAILURE:
1442  /* AFPRead in error: best to reset the socket */
1443  SCLogWarning("%s: read failure: %s", ptv->iface, strerror(errno));
1444  AFPSwitchState(ptv, AFP_STATE_DOWN);
1445  continue;
1446  case AFP_SURI_FAILURE:
1447  StatsIncr(ptv->tv, ptv->capture_errors);
1448  break;
1449  case AFP_KERNEL_DROP:
1450  AFPDumpCounters(ptv);
1451  break;
1452  }
1453  } else if (unlikely(r == 0)) {
1455  /* Trigger one dump of stats every second */
1456  current_time = time(NULL);
1457  if (current_time != last_dump) {
1458  AFPDumpCounters(ptv);
1459  last_dump = current_time;
1460  }
1461  /* poll timed out, lets see handle our timeout path */
1462  TmThreadsCaptureHandleTimeout(tv, NULL);
1463 
1464  } else if ((r < 0) && (errno != EINTR)) {
1465  StatsIncr(ptv->tv, ptv->capture_afp_poll_err);
1466  SCLogWarning("%s: poll failure: %s", ptv->iface, strerror(errno));
1467  AFPSwitchState(ptv, AFP_STATE_DOWN);
1468  continue;
1469  }
1471  }
1472 
1473  AFPDumpCounters(ptv);
1476 }
1477 
1478 static int AFPGetDevFlags(int fd, const char *ifname)
1479 {
1480  struct ifreq ifr;
1481 
1482  memset(&ifr, 0, sizeof(ifr));
1483  strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1484 
1485  if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
1486  SCLogError("%s: failed to get interface flags: %s", ifname, strerror(errno));
1487  return -1;
1488  }
1489 
1490  return ifr.ifr_flags;
1491 }
1492 
1493 
1494 static int AFPGetIfnumByDev(int fd, const char *ifname, int verbose)
1495 {
1496  struct ifreq ifr;
1497 
1498  memset(&ifr, 0, sizeof(ifr));
1499  strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1500 
1501  if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) {
1502  if (verbose)
1503  SCLogError("%s: failed to find interface: %s", ifname, strerror(errno));
1504  return -1;
1505  }
1506 
1507  return ifr.ifr_ifindex;
1508 }
1509 
1510 static int AFPGetDevLinktype(int fd, const char *ifname)
1511 {
1512  struct ifreq ifr;
1513 
1514  memset(&ifr, 0, sizeof(ifr));
1515  strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1516 
1517  if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
1518  SCLogError("%s: failed to find interface type: %s", ifname, strerror(errno));
1519  return -1;
1520  }
1521 
1522  switch (ifr.ifr_hwaddr.sa_family) {
1523  case ARPHRD_LOOPBACK:
1524  return LINKTYPE_ETHERNET;
1525  case ARPHRD_PPP:
1526  case ARPHRD_NONE:
1527  return LINKTYPE_RAW;
1528  default:
1529  return ifr.ifr_hwaddr.sa_family;
1530  }
1531 }
1532 
1533 int AFPGetLinkType(const char *ifname)
1534 {
1535  int ltype;
1536 
1537  int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
1538  if (fd == -1) {
1539  SCLogError("%s: failed to create AF_PACKET socket: %s", ifname, strerror(errno));
1540  return LINKTYPE_RAW;
1541  }
1542 
1543  ltype = AFPGetDevLinktype(fd, ifname);
1544  close(fd);
1545 
1546  DatalinkSetGlobalType(ltype);
1547 
1548  return ltype;
1549 }
1550 
1551 static int AFPComputeRingParams(AFPThreadVars *ptv, int order)
1552 {
1553  /* Compute structure:
1554  Target is to store all pending packets
1555  with a size equal to MTU + auxdata
1556  And we keep a decent number of block
1557 
1558  To do so:
1559  Compute frame_size (aligned to be able to fit in block
1560  Check which block size we need. Blocksize is a 2^n * pagesize
1561  We then need to get order, big enough to have
1562  frame_size < block size
1563  Find number of frame per block (divide)
1564  Fill in packet_req
1565 
1566  Compute frame size:
1567  described in packet_mmap.txt
1568  dependent on snaplen (need to use a variable ?)
1569 snaplen: MTU ?
1570 tp_hdrlen determine_version in daq_afpacket
1571 in V1: sizeof(struct tpacket_hdr);
1572 in V2: val in getsockopt(instance->fd, SOL_PACKET, PACKET_HDRLEN, &val, &len)
1573 frame size: TPACKET_ALIGN(snaplen + TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct
1574 sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
1575 
1576  */
1577  int tp_hdrlen = sizeof(struct tpacket_hdr);
1578  int snaplen = default_packet_size;
1579 
1580  if (snaplen == 0) {
1581  snaplen = GetIfaceMaxPacketSize(ptv->livedev);
1582  if (snaplen <= 0) {
1583  SCLogWarning("%s: unable to get MTU, setting snaplen default of 1514", ptv->iface);
1584  snaplen = 1514;
1585  }
1586  }
1587 
1588  ptv->req.v2.tp_frame_size = TPACKET_ALIGN(snaplen +TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
1589  ptv->req.v2.tp_block_size = getpagesize() << order;
1590  int frames_per_block = ptv->req.v2.tp_block_size / ptv->req.v2.tp_frame_size;
1591  if (frames_per_block == 0) {
1592  SCLogError("%s: Frame size bigger than block size", ptv->iface);
1593  return -1;
1594  }
1595  ptv->req.v2.tp_frame_nr = ptv->ring_size;
1596  ptv->req.v2.tp_block_nr = ptv->req.v2.tp_frame_nr / frames_per_block + 1;
1597  /* exact division */
1598  ptv->req.v2.tp_frame_nr = ptv->req.v2.tp_block_nr * frames_per_block;
1599  SCLogPerf("%s: rx ring: block_size=%d block_nr=%d frame_size=%d frame_nr=%d", ptv->iface,
1600  ptv->req.v2.tp_block_size, ptv->req.v2.tp_block_nr, ptv->req.v2.tp_frame_size,
1601  ptv->req.v2.tp_frame_nr);
1602  return 1;
1603 }
1604 
1605 #ifdef HAVE_TPACKET_V3
1606 static int AFPComputeRingParamsV3(AFPThreadVars *ptv)
1607 {
1608  ptv->req.v3.tp_block_size = ptv->block_size;
1609  ptv->req.v3.tp_frame_size = 2048;
1610  int frames_per_block = 0;
1611  int tp_hdrlen = sizeof(struct tpacket3_hdr);
1612  int snaplen = default_packet_size;
1613 
1614  if (snaplen == 0) {
1615  snaplen = GetIfaceMaxPacketSize(ptv->livedev);
1616  if (snaplen <= 0) {
1617  SCLogWarning("%s: unable to get MTU, setting snaplen default of 1514", ptv->iface);
1618  snaplen = 1514;
1619  }
1620  }
1621 
1622  ptv->req.v3.tp_frame_size = TPACKET_ALIGN(snaplen +TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
1623  frames_per_block = ptv->req.v3.tp_block_size / ptv->req.v3.tp_frame_size;
1624 
1625  if (frames_per_block == 0) {
1626  SCLogError("%s: block size is too small, it should be at least %d", ptv->iface,
1627  ptv->req.v3.tp_frame_size);
1628  return -1;
1629  }
1630  ptv->req.v3.tp_block_nr = ptv->ring_size / frames_per_block + 1;
1631  /* exact division */
1632  ptv->req.v3.tp_frame_nr = ptv->req.v3.tp_block_nr * frames_per_block;
1633  ptv->req.v3.tp_retire_blk_tov = ptv->block_timeout;
1634  ptv->req.v3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
1635  SCLogPerf("%s: rx ring params: block_size=%d block_nr=%d frame_size=%d frame_nr=%d (mem: %d)",
1636  ptv->iface, ptv->req.v3.tp_block_size, ptv->req.v3.tp_block_nr,
1637  ptv->req.v3.tp_frame_size, ptv->req.v3.tp_frame_nr,
1638  ptv->req.v3.tp_block_size * ptv->req.v3.tp_block_nr);
1639  return 1;
1640 }
1641 #endif
1642 
1643 static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
1644 {
1645  int val;
1646  unsigned int len = sizeof(val), i;
1647  int order;
1648  int r, mmap_flag;
1649 
1650 #ifdef HAVE_TPACKET_V3
1651  if (ptv->flags & AFP_TPACKET_V3) {
1652  val = TPACKET_V3;
1653  } else
1654 #endif
1655  {
1656  val = TPACKET_V2;
1657  }
1658  if (getsockopt(ptv->socket, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0) {
1659  if (errno == ENOPROTOOPT) {
1660  if (ptv->flags & AFP_TPACKET_V3) {
1661  SCLogError("%s: kernel too old for TPACKET_V3 (need 3.2+)", devname);
1662  } else {
1663  SCLogError("%s: kernel too old (need 2.6.27+)", devname);
1664  }
1665  }
1666  SCLogError("%s: failed to retrieve packet header len", devname);
1667  return AFP_FATAL_ERROR;
1668  }
1669 
1670  val = TPACKET_V2;
1671 #ifdef HAVE_TPACKET_V3
1672  if (ptv->flags & AFP_TPACKET_V3) {
1673  val = TPACKET_V3;
1674  }
1675 #endif
1676  if (setsockopt(ptv->socket, SOL_PACKET, PACKET_VERSION, &val,
1677  sizeof(val)) < 0) {
1678  SCLogError("%s: failed to activate TPACKET_V2/TPACKET_V3 on packet socket: %s", devname,
1679  strerror(errno));
1680  return AFP_FATAL_ERROR;
1681  }
1682 
1683 #ifdef HAVE_HW_TIMESTAMPING
1684  int req = SOF_TIMESTAMPING_RAW_HARDWARE;
1685  if (setsockopt(ptv->socket, SOL_PACKET, PACKET_TIMESTAMP, (void *) &req,
1686  sizeof(req)) < 0) {
1687  SCLogWarning("%s: failed to activate hardware timestamping on packet socket: %s", devname,
1688  strerror(errno));
1689  }
1690 #endif
1691 
1692  /* Reserve head room for a VLAN header. One vlan is extracted from AFP header
1693  * so one VLAN header length is enough. */
1694  int reserve = VLAN_HEADER_LEN;
1695  if (setsockopt(ptv->socket, SOL_PACKET, PACKET_RESERVE, (void *)&reserve, sizeof(reserve)) <
1696  0) {
1697  SCLogError("%s: failed to activate reserve on packet socket: %s", devname, strerror(errno));
1698  return AFP_FATAL_ERROR;
1699  }
1700 
1701  /* Allocate RX ring */
1702 #ifdef HAVE_TPACKET_V3
1703  if (ptv->flags & AFP_TPACKET_V3) {
1704  if (AFPComputeRingParamsV3(ptv) != 1) {
1705  return AFP_FATAL_ERROR;
1706  }
1707  r = setsockopt(ptv->socket, SOL_PACKET, PACKET_RX_RING,
1708  (void *) &ptv->req.v3, sizeof(ptv->req.v3));
1709  if (r < 0) {
1710  SCLogError("%s: failed to allocate RX Ring: %s", devname, strerror(errno));
1711  return AFP_FATAL_ERROR;
1712  }
1713  } else {
1714 #endif
1715  for (order = AFP_BLOCK_SIZE_DEFAULT_ORDER; order >= 0; order--) {
1716  if (AFPComputeRingParams(ptv, order) != 1) {
1717  SCLogError("%s: ring parameters are incorrect. Please file a bug report", devname);
1718  return AFP_FATAL_ERROR;
1719  }
1720 
1721  r = setsockopt(ptv->socket, SOL_PACKET, PACKET_RX_RING,
1722  (void *) &ptv->req, sizeof(ptv->req));
1723 
1724  if (r < 0) {
1725  if (errno == ENOMEM) {
1726  SCLogWarning("%s: memory issue with ring parameters. Retrying", devname);
1727  continue;
1728  }
1729  SCLogError("%s: failed to setup RX Ring: %s", devname, strerror(errno));
1730  return AFP_FATAL_ERROR;
1731  } else {
1732  break;
1733  }
1734  }
1735  if (order < 0) {
1736  SCLogError("%s: failed to setup RX Ring (order 0 failed)", devname);
1737  return AFP_FATAL_ERROR;
1738  }
1739 #ifdef HAVE_TPACKET_V3
1740  }
1741 #endif
1742 
1743  /* Allocate the Ring */
1744 #ifdef HAVE_TPACKET_V3
1745  if (ptv->flags & AFP_TPACKET_V3) {
1746  ptv->ring_buflen = ptv->req.v3.tp_block_nr * ptv->req.v3.tp_block_size;
1747  } else {
1748 #endif
1749  ptv->ring_buflen = ptv->req.v2.tp_block_nr * ptv->req.v2.tp_block_size;
1750 #ifdef HAVE_TPACKET_V3
1751  }
1752 #endif
1753  mmap_flag = MAP_SHARED;
1754  if (ptv->flags & AFP_MMAP_LOCKED)
1755  mmap_flag |= MAP_LOCKED;
1756  ptv->ring_buf = mmap(0, ptv->ring_buflen, PROT_READ|PROT_WRITE,
1757  mmap_flag, ptv->socket, 0);
1758  if (ptv->ring_buf == MAP_FAILED) {
1759  SCLogError("%s: failed to mmap: %s", devname, strerror(errno));
1760  goto mmap_err;
1761  }
1762 #ifdef HAVE_TPACKET_V3
1763  if (ptv->flags & AFP_TPACKET_V3) {
1764  ptv->ring.v3 = SCMalloc(ptv->req.v3.tp_block_nr * sizeof(*ptv->ring.v3));
1765  if (!ptv->ring.v3) {
1766  SCLogError("%s: failed to alloc ring: %s", devname, strerror(errno));
1767  goto postmmap_err;
1768  }
1769  for (i = 0; i < ptv->req.v3.tp_block_nr; ++i) {
1770  ptv->ring.v3[i].iov_base = ptv->ring_buf + (i * ptv->req.v3.tp_block_size);
1771  ptv->ring.v3[i].iov_len = ptv->req.v3.tp_block_size;
1772  }
1773  } else {
1774 #endif
1775  /* allocate a ring for each frame header pointer*/
1776  ptv->ring.v2 = SCCalloc(ptv->req.v2.tp_frame_nr, sizeof(union thdr *));
1777  if (ptv->ring.v2 == NULL) {
1778  SCLogError("%s: failed to alloc ring: %s", devname, strerror(errno));
1779  goto postmmap_err;
1780  }
1781  /* fill the header ring with proper frame ptr*/
1782  ptv->frame_offset = 0;
1783  for (i = 0; i < ptv->req.v2.tp_block_nr; ++i) {
1784  void *base = &(ptv->ring_buf[i * ptv->req.v2.tp_block_size]);
1785  unsigned int j;
1786  for (j = 0; j < ptv->req.v2.tp_block_size / ptv->req.v2.tp_frame_size; ++j, ++ptv->frame_offset) {
1787  (((union thdr **)ptv->ring.v2)[ptv->frame_offset]) = base;
1788  base += ptv->req.v2.tp_frame_size;
1789  }
1790  }
1791  ptv->frame_offset = 0;
1792 #ifdef HAVE_TPACKET_V3
1793  }
1794 #endif
1795 
1796  return 0;
1797 
1798 postmmap_err:
1799  munmap(ptv->ring_buf, ptv->ring_buflen);
1800  if (ptv->ring.v2)
1801  SCFree(ptv->ring.v2);
1802  if (ptv->ring.v3)
1803  SCFree(ptv->ring.v3);
1804 mmap_err:
1805  /* Packet mmap does the cleaning when socket is closed */
1806  return AFP_FATAL_ERROR;
1807 }
1808 
1809 /** \brief test if we can use FANOUT. Older kernels like those in
1810  * CentOS6 have HAVE_PACKET_FANOUT defined but fail to work
1811  */
1812 int AFPIsFanoutSupported(uint16_t cluster_id)
1813 {
1814 #ifdef HAVE_PACKET_FANOUT
1815  int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
1816  if (fd < 0)
1817  return 0;
1818 
1820  uint32_t option = (mode << 16) | cluster_id;
1821  int r = setsockopt(fd, SOL_PACKET, PACKET_FANOUT,(void *)&option, sizeof(option));
1822  close(fd);
1823 
1824  if (r < 0) {
1825  SCLogError("fanout not supported by kernel: "
1826  "Kernel too old or cluster-id %d already in use.",
1827  cluster_id);
1828  return 0;
1829  }
1830  return 1;
1831 #else
1832  return 0;
1833 #endif
1834 }
1835 
1836 #ifdef HAVE_PACKET_EBPF
1837 
1838 static int SockFanoutSeteBPF(AFPThreadVars *ptv)
1839 {
1840  int pfd = ptv->ebpf_lb_fd;
1841  if (pfd == -1) {
1842  SCLogError("Fanout file descriptor is invalid");
1843  return -1;
1844  }
1845 
1846  if (setsockopt(ptv->socket, SOL_PACKET, PACKET_FANOUT_DATA, &pfd, sizeof(pfd))) {
1847  SCLogError("Error setting ebpf");
1848  return -1;
1849  }
1850  SCLogInfo("Activated eBPF on socket");
1851 
1852  return 0;
1853 }
1854 
1855 static int SetEbpfFilter(AFPThreadVars *ptv)
1856 {
1857  int pfd = ptv->ebpf_filter_fd;
1858  if (pfd == -1) {
1859  SCLogError("Filter file descriptor is invalid");
1860  return -1;
1861  }
1862 
1863  if (setsockopt(ptv->socket, SOL_SOCKET, SO_ATTACH_BPF, &pfd, sizeof(pfd))) {
1864  SCLogError("Error setting ebpf: %s", strerror(errno));
1865  return -1;
1866  }
1867  SCLogInfo("Activated eBPF filter on socket");
1868 
1869  return 0;
1870 }
1871 #endif
1872 
1873 static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose)
1874 {
1875  int r;
1876  int ret = AFP_FATAL_ERROR;
1877  struct packet_mreq sock_params;
1878  struct sockaddr_ll bind_address;
1879  int if_idx;
1880 
1881  /* open socket */
1882  ptv->socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
1883  if (ptv->socket == -1) {
1884  SCLogError("%s: failed to create socket: %s", devname, strerror(errno));
1885  goto error;
1886  }
1887 
1888  if_idx = AFPGetIfnumByDev(ptv->socket, devname, verbose);
1889  if (if_idx == -1) {
1890  goto socket_err;
1891  }
1892 
1893  /* bind socket */
1894  memset(&bind_address, 0, sizeof(bind_address));
1895  bind_address.sll_family = AF_PACKET;
1896  bind_address.sll_protocol = htons(ETH_P_ALL);
1897  bind_address.sll_ifindex = if_idx;
1898  if (bind_address.sll_ifindex == -1) {
1899  if (verbose)
1900  SCLogWarning("%s: device for found", devname);
1901  ret = AFP_RECOVERABLE_ERROR;
1902  goto socket_err;
1903  }
1904 
1905  int if_flags = AFPGetDevFlags(ptv->socket, ptv->iface);
1906  if (if_flags == -1) {
1907  if (verbose) {
1908  SCLogWarning("%s: failed to get interface flags", ptv->iface);
1909  }
1910  ret = AFP_RECOVERABLE_ERROR;
1911  goto socket_err;
1912  } else if ((if_flags & (IFF_UP | IFF_RUNNING)) == 0) {
1913  if (verbose) {
1914  SCLogWarning("%s: interface is down", ptv->iface);
1915  }
1916  ret = AFP_RECOVERABLE_ERROR;
1917  goto socket_err;
1918  }
1919 
1920  /* ignore outgoing packets on loopback interfaces */
1921  if (if_flags & IFF_LOOPBACK)
1922  ptv->pkttype_filter_mask |= BIT_U32(PACKET_OUTGOING);
1923 
1924  if (ptv->promisc != 0) {
1925  /* Force promiscuous mode */
1926  memset(&sock_params, 0, sizeof(sock_params));
1927  sock_params.mr_type = PACKET_MR_PROMISC;
1928  sock_params.mr_ifindex = bind_address.sll_ifindex;
1929  r = setsockopt(ptv->socket, SOL_PACKET, PACKET_ADD_MEMBERSHIP,(void *)&sock_params, sizeof(sock_params));
1930  if (r < 0) {
1931  SCLogError("%s: failed to set promisc mode: %s", devname, strerror(errno));
1932  goto socket_err;
1933  }
1934  }
1935 
1937  int val = 1;
1938  if (setsockopt(ptv->socket, SOL_PACKET, PACKET_AUXDATA, &val,
1939  sizeof(val)) == -1 && errno != ENOPROTOOPT) {
1940  SCLogWarning(
1941  "%s: 'kernel' checksum mode not supported, falling back to full mode", devname);
1943  }
1944  }
1945 
1946  /* set socket recv buffer size */
1947  if (ptv->buffer_size != 0) {
1948  /*
1949  * Set the socket buffer size to the specified value.
1950  */
1951  SCLogPerf("%s: setting socket buffer to %d", devname, ptv->buffer_size);
1952  if (setsockopt(ptv->socket, SOL_SOCKET, SO_RCVBUF,
1953  &ptv->buffer_size,
1954  sizeof(ptv->buffer_size)) == -1) {
1955  SCLogError("%s: failed to set buffer size to %d: %s", devname, ptv->buffer_size,
1956  strerror(errno));
1957  goto socket_err;
1958  }
1959  }
1960 
1961  r = bind(ptv->socket, (struct sockaddr *)&bind_address, sizeof(bind_address));
1962  if (r < 0) {
1963  if (verbose) {
1964  if (errno == ENETDOWN) {
1965  SCLogWarning("%s: failed to bind socket, iface is down", devname);
1966  } else {
1967  SCLogWarning("%s: failed to bind socket: %s", devname, strerror(errno));
1968  }
1969  }
1970  ret = AFP_RECOVERABLE_ERROR;
1971  goto socket_err;
1972  }
1973 
1974 
1975 #ifdef HAVE_PACKET_FANOUT
1976  /* add bound socket to fanout group */
1977  if (ptv->threads > 1) {
1978  uint32_t mode = ptv->cluster_type;
1979  uint16_t id = ptv->cluster_id;
1980  uint32_t option = (mode << 16) | (id & 0xffff);
1981  r = setsockopt(ptv->socket, SOL_PACKET, PACKET_FANOUT,(void *)&option, sizeof(option));
1982  if (r < 0) {
1983  SCLogError("%s: failed to set fanout mode: %s", devname, strerror(errno));
1984  goto socket_err;
1985  }
1986  }
1987 #endif
1988 
1989 #ifdef HAVE_PACKET_EBPF
1990  if (ptv->cluster_type == PACKET_FANOUT_EBPF) {
1991  r = SockFanoutSeteBPF(ptv);
1992  if (r < 0) {
1993  SCLogError("%s: failed to set eBPF: %s", devname, strerror(errno));
1994  goto socket_err;
1995  }
1996  }
1997 #endif
1998 
1999  ret = AFPSetupRing(ptv, devname);
2000  if (ret != 0)
2001  goto socket_err;
2002 
2003  SCLogDebug("Using interface '%s' via socket %d", (char *)devname, ptv->socket);
2004 
2005  ptv->datalink = AFPGetDevLinktype(ptv->socket, ptv->iface);
2006 
2007  TmEcode rc = AFPSetBPFFilter(ptv);
2008  if (rc == TM_ECODE_FAILED) {
2009  ret = AFP_FATAL_ERROR;
2010  goto socket_err;
2011  }
2012 
2013  /* Init is ok */
2014  AFPSwitchState(ptv, AFP_STATE_UP);
2015  return 0;
2016 
2017 socket_err:
2018  close(ptv->socket);
2019  ptv->socket = -1;
2020  if (ptv->flags & AFP_TPACKET_V3) {
2021  if (ptv->ring.v3) {
2022  SCFree(ptv->ring.v3);
2023  ptv->ring.v3 = NULL;
2024  }
2025  } else {
2026  if (ptv->ring.v2) {
2027  SCFree(ptv->ring.v2);
2028  ptv->ring.v2 = NULL;
2029  }
2030  }
2031 
2032 error:
2033  return -ret;
2034 }
2035 
2036 TmEcode AFPSetBPFFilter(AFPThreadVars *ptv)
2037 {
2038  struct bpf_program filter;
2039  struct sock_fprog fcode;
2040  int rc;
2041 
2042 #ifdef HAVE_PACKET_EBPF
2043  if (ptv->ebpf_filter_fd != -1) {
2044  return SetEbpfFilter(ptv);
2045  }
2046 #endif
2047 
2048  if (!ptv->bpf_filter)
2049  return TM_ECODE_OK;
2050 
2051  SCLogInfo("%s: using BPF '%s'", ptv->iface, ptv->bpf_filter);
2052 
2053  char errbuf[PCAP_ERRBUF_SIZE];
2054  if (SCBPFCompile(default_packet_size, /* snaplen_arg */
2055  ptv->datalink, /* linktype_arg */
2056  &filter, /* program */
2057  ptv->bpf_filter, /* const char *buf */
2058  1, /* optimize */
2059  0, /* mask */
2060  errbuf,
2061  sizeof(errbuf)) == -1) {
2062  SCLogError("%s: failed to compile BPF \"%s\": %s", ptv->iface, ptv->bpf_filter, errbuf);
2063  return TM_ECODE_FAILED;
2064  }
2065 
2066  if (filter.bf_len > USHRT_MAX) {
2067  return TM_ECODE_FAILED;
2068  }
2069  fcode.len = (unsigned short)filter.bf_len;
2070  fcode.filter = (struct sock_filter*)filter.bf_insns;
2071 
2072  rc = setsockopt(ptv->socket, SOL_SOCKET, SO_ATTACH_FILTER, &fcode, sizeof(fcode));
2073 
2074  SCBPFFree(&filter);
2075  if(rc == -1) {
2076  SCLogError("%s: failed to attach filter: %s", ptv->iface, strerror(errno));
2077  return TM_ECODE_FAILED;
2078  }
2079 
2080  return TM_ECODE_OK;
2081 }
2082 
2083 #ifdef HAVE_PACKET_EBPF
2084 /**
2085  * Insert a half flow in the kernel bypass table
2086  *
2087  * \param mapfd file descriptor of the protocol bypass table
2088  * \param key data to use as key in the table
2089  * \return 0 in case of error, 1 if success
2090  */
2091 static int AFPInsertHalfFlow(int mapd, void *key, unsigned int nr_cpus)
2092 {
2093  BPF_DECLARE_PERCPU(struct pair, value, nr_cpus);
2094  unsigned int i;
2095 
2096  if (mapd == -1) {
2097  return 0;
2098  }
2099 
2100  /* We use a per CPU structure so we have to set an array of values as the kernel
2101  * is not duplicating the data on each CPU by itself. */
2102  for (i = 0; i < nr_cpus; i++) {
2103  BPF_PERCPU(value, i).packets = 0;
2104  BPF_PERCPU(value, i).bytes = 0;
2105  }
2106  if (bpf_map_update_elem(mapd, key, value, BPF_NOEXIST) != 0) {
2107  switch (errno) {
2108  /* no more place in the hash */
2109  case E2BIG:
2110  return 0;
2111  /* no more place in the hash for some hardware bypass */
2112  case EAGAIN:
2113  return 0;
2114  /* if we already have the key then bypass is a success */
2115  case EEXIST:
2116  return 1;
2117  /* Not supposed to be there so issue a error */
2118  default:
2119  SCLogError("Can't update eBPF map: %s (%d)", strerror(errno), errno);
2120  return 0;
2121  }
2122  }
2123  return 1;
2124 }
2125 
2126 static int AFPSetFlowStorage(Packet *p, int map_fd, void *key0, void* key1,
2127  int family)
2128 {
2130  if (fc) {
2131  if (fc->bypass_data != NULL) {
2132  // bypass already activated
2133  SCFree(key0);
2134  SCFree(key1);
2135  return 1;
2136  }
2137  EBPFBypassData *eb = SCCalloc(1, sizeof(EBPFBypassData));
2138  if (eb == NULL) {
2139  EBPFDeleteKey(map_fd, key0);
2140  EBPFDeleteKey(map_fd, key1);
2141  LiveDevAddBypassFail(p->livedev, 1, family);
2142  SCFree(key0);
2143  SCFree(key1);
2144  return 0;
2145  }
2146  eb->key[0] = key0;
2147  eb->key[1] = key1;
2148  eb->mapfd = map_fd;
2149  eb->cpus_count = p->afp_v.nr_cpus;
2150  fc->BypassUpdate = EBPFBypassUpdate;
2151  fc->BypassFree = EBPFBypassFree;
2152  fc->bypass_data = eb;
2153  } else {
2154  EBPFDeleteKey(map_fd, key0);
2155  EBPFDeleteKey(map_fd, key1);
2156  LiveDevAddBypassFail(p->livedev, 1, family);
2157  SCFree(key0);
2158  SCFree(key1);
2159  return 0;
2160  }
2161 
2162  LiveDevAddBypassStats(p->livedev, 1, family);
2163  LiveDevAddBypassSuccess(p->livedev, 1, family);
2164  return 1;
2165 }
2166 
2167 /**
2168  * Bypass function for AF_PACKET capture in eBPF mode
2169  *
2170  * This function creates two half flows in the map shared with the kernel
2171  * to trigger bypass.
2172  *
2173  * The implementation of bypass is done via an IPv4 and an IPv6 flow table.
2174  * This table contains the list of half flows to bypass. The in-kernel filter
2175  * will skip/drop the packet if they belong to a flow in one of the flows
2176  * table.
2177  *
2178  * \param p the packet belonging to the flow to bypass
2179  * \return 0 if unable to bypass, 1 if success
2180  */
2181 static int AFPBypassCallback(Packet *p)
2182 {
2183  SCLogDebug("Calling af_packet callback function");
2184  /* Only bypass TCP and UDP */
2185  if (!(PKT_IS_TCP(p) || PKT_IS_UDP(p))) {
2186  return 0;
2187  }
2188 
2189  /* If we don't have a flow attached to packet the eBPF map entries
2190  * will be destroyed at first flow bypass manager pass as we won't
2191  * find any associated entry */
2192  if (p->flow == NULL) {
2193  return 0;
2194  }
2195  /* Bypassing tunneled packets is currently not supported
2196  * because we can't discard the inner packet only due to
2197  * primitive parsing in eBPF */
2198  if (IS_TUNNEL_PKT(p)) {
2199  return 0;
2200  }
2201  if (PKT_IS_IPV4(p)) {
2202  SCLogDebug("add an IPv4");
2203  if (p->afp_v.v4_map_fd == -1) {
2204  return 0;
2205  }
2206  struct flowv4_keys *keys[2];
2207  keys[0] = SCCalloc(1, sizeof(struct flowv4_keys));
2208  if (keys[0] == NULL) {
2209  return 0;
2210  }
2211  keys[0]->src = htonl(GET_IPV4_SRC_ADDR_U32(p));
2212  keys[0]->dst = htonl(GET_IPV4_DST_ADDR_U32(p));
2213  keys[0]->port16[0] = GET_TCP_SRC_PORT(p);
2214  keys[0]->port16[1] = GET_TCP_DST_PORT(p);
2215  keys[0]->vlan0 = p->vlan_id[0];
2216  keys[0]->vlan1 = p->vlan_id[1];
2217  keys[0]->vlan2 = p->vlan_id[2];
2218 
2219  if (IPV4_GET_IPPROTO(p) == IPPROTO_TCP) {
2220  keys[0]->ip_proto = 1;
2221  } else {
2222  keys[0]->ip_proto = 0;
2223  }
2224  if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[0],
2225  p->afp_v.nr_cpus) == 0) {
2226  LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2227  SCFree(keys[0]);
2228  return 0;
2229  }
2230  keys[1]= SCCalloc(1, sizeof(struct flowv4_keys));
2231  if (keys[1] == NULL) {
2232  EBPFDeleteKey(p->afp_v.v4_map_fd, keys[0]);
2233  LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2234  SCFree(keys[0]);
2235  return 0;
2236  }
2237  keys[1]->src = htonl(GET_IPV4_DST_ADDR_U32(p));
2238  keys[1]->dst = htonl(GET_IPV4_SRC_ADDR_U32(p));
2239  keys[1]->port16[0] = GET_TCP_DST_PORT(p);
2240  keys[1]->port16[1] = GET_TCP_SRC_PORT(p);
2241  keys[1]->vlan0 = p->vlan_id[0];
2242  keys[1]->vlan1 = p->vlan_id[1];
2243  keys[1]->vlan2 = p->vlan_id[2];
2244 
2245  keys[1]->ip_proto = keys[0]->ip_proto;
2246  if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[1],
2247  p->afp_v.nr_cpus) == 0) {
2248  EBPFDeleteKey(p->afp_v.v4_map_fd, keys[0]);
2249  LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2250  SCFree(keys[0]);
2251  SCFree(keys[1]);
2252  return 0;
2253  }
2254  EBPFUpdateFlow(p->flow, p, NULL);
2255  return AFPSetFlowStorage(p, p->afp_v.v4_map_fd, keys[0], keys[1], AF_INET);
2256  }
2257  /* For IPv6 case we don't handle extended header in eBPF */
2258  if (PKT_IS_IPV6(p) &&
2259  ((IPV6_GET_NH(p) == IPPROTO_TCP) || (IPV6_GET_NH(p) == IPPROTO_UDP))) {
2260  int i;
2261  if (p->afp_v.v6_map_fd == -1) {
2262  return 0;
2263  }
2264  SCLogDebug("add an IPv6");
2265  struct flowv6_keys *keys[2];
2266  keys[0] = SCCalloc(1, sizeof(struct flowv6_keys));
2267  if (keys[0] == NULL) {
2268  LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2269  return 0;
2270  }
2271  for (i = 0; i < 4; i++) {
2272  keys[0]->src[i] = ntohl(GET_IPV6_SRC_ADDR(p)[i]);
2273  keys[0]->dst[i] = ntohl(GET_IPV6_DST_ADDR(p)[i]);
2274  }
2275  keys[0]->port16[0] = GET_TCP_SRC_PORT(p);
2276  keys[0]->port16[1] = GET_TCP_DST_PORT(p);
2277  keys[0]->vlan0 = p->vlan_id[0];
2278  keys[0]->vlan1 = p->vlan_id[1];
2279  keys[0]->vlan2 = p->vlan_id[2];
2280 
2281  if (IPV6_GET_NH(p) == IPPROTO_TCP) {
2282  keys[0]->ip_proto = 1;
2283  } else {
2284  keys[0]->ip_proto = 0;
2285  }
2286  if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[0],
2287  p->afp_v.nr_cpus) == 0) {
2288  LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2289  SCFree(keys[0]);
2290  return 0;
2291  }
2292  keys[1]= SCCalloc(1, sizeof(struct flowv6_keys));
2293  if (keys[1] == NULL) {
2294  EBPFDeleteKey(p->afp_v.v6_map_fd, keys[0]);
2295  LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2296  SCFree(keys[0]);
2297  return 0;
2298  }
2299  for (i = 0; i < 4; i++) {
2300  keys[1]->src[i] = ntohl(GET_IPV6_DST_ADDR(p)[i]);
2301  keys[1]->dst[i] = ntohl(GET_IPV6_SRC_ADDR(p)[i]);
2302  }
2303  keys[1]->port16[0] = GET_TCP_DST_PORT(p);
2304  keys[1]->port16[1] = GET_TCP_SRC_PORT(p);
2305  keys[1]->vlan0 = p->vlan_id[0];
2306  keys[1]->vlan1 = p->vlan_id[1];
2307  keys[1]->vlan2 = p->vlan_id[2];
2308 
2309  keys[1]->ip_proto = keys[0]->ip_proto;
2310  if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[1],
2311  p->afp_v.nr_cpus) == 0) {
2312  EBPFDeleteKey(p->afp_v.v6_map_fd, keys[0]);
2313  LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2314  SCFree(keys[0]);
2315  SCFree(keys[1]);
2316  return 0;
2317  }
2318  if (p->flow)
2319  EBPFUpdateFlow(p->flow, p, NULL);
2320  return AFPSetFlowStorage(p, p->afp_v.v6_map_fd, keys[0], keys[1], AF_INET6);
2321  }
2322  return 0;
2323 }
2324 
2325 /**
2326  * Bypass function for AF_PACKET capture in XDP mode
2327  *
2328  * This function creates two half flows in the map shared with the kernel
2329  * to trigger bypass. This function is similar to AFPBypassCallback() but
2330  * the bytes order is changed for some data due to the way we get the data
2331  * in the XDP case.
2332  *
2333  * \param p the packet belonging to the flow to bypass
2334  * \return 0 if unable to bypass, 1 if success
2335  */
2336 static int AFPXDPBypassCallback(Packet *p)
2337 {
2338  SCLogDebug("Calling af_packet callback function");
2339  /* Only bypass TCP and UDP */
2340  if (!(PKT_IS_TCP(p) || PKT_IS_UDP(p))) {
2341  return 0;
2342  }
2343 
2344  /* If we don't have a flow attached to packet the eBPF map entries
2345  * will be destroyed at first flow bypass manager pass as we won't
2346  * find any associated entry */
2347  if (p->flow == NULL) {
2348  return 0;
2349  }
2350  /* Bypassing tunneled packets is currently not supported
2351  * because we can't discard the inner packet only due to
2352  * primitive parsing in eBPF */
2353  if (IS_TUNNEL_PKT(p)) {
2354  return 0;
2355  }
2356  if (PKT_IS_IPV4(p)) {
2357  struct flowv4_keys *keys[2];
2358  keys[0]= SCCalloc(1, sizeof(struct flowv4_keys));
2359  if (keys[0] == NULL) {
2360  LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2361  return 0;
2362  }
2363  if (p->afp_v.v4_map_fd == -1) {
2364  SCFree(keys[0]);
2365  return 0;
2366  }
2367  keys[0]->src = p->src.addr_data32[0];
2368  keys[0]->dst = p->dst.addr_data32[0];
2369  /* In the XDP filter we get port from parsing of packet and not from skb
2370  * (as in eBPF filter) so we need to pass from host to network order */
2371  keys[0]->port16[0] = htons(p->sp);
2372  keys[0]->port16[1] = htons(p->dp);
2373  keys[0]->vlan0 = p->vlan_id[0];
2374  keys[0]->vlan1 = p->vlan_id[1];
2375  keys[0]->vlan2 = p->vlan_id[2];
2376  if (IPV4_GET_IPPROTO(p) == IPPROTO_TCP) {
2377  keys[0]->ip_proto = 1;
2378  } else {
2379  keys[0]->ip_proto = 0;
2380  }
2381  if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[0],
2382  p->afp_v.nr_cpus) == 0) {
2383  LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2384  SCFree(keys[0]);
2385  return 0;
2386  }
2387  keys[1]= SCCalloc(1, sizeof(struct flowv4_keys));
2388  if (keys[1] == NULL) {
2389  EBPFDeleteKey(p->afp_v.v4_map_fd, keys[0]);
2390  LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2391  SCFree(keys[0]);
2392  return 0;
2393  }
2394  keys[1]->src = p->dst.addr_data32[0];
2395  keys[1]->dst = p->src.addr_data32[0];
2396  keys[1]->port16[0] = htons(p->dp);
2397  keys[1]->port16[1] = htons(p->sp);
2398  keys[1]->vlan0 = p->vlan_id[0];
2399  keys[1]->vlan1 = p->vlan_id[1];
2400  keys[1]->vlan2 = p->vlan_id[2];
2401  keys[1]->ip_proto = keys[0]->ip_proto;
2402  if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[1],
2403  p->afp_v.nr_cpus) == 0) {
2404  EBPFDeleteKey(p->afp_v.v4_map_fd, keys[0]);
2405  LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2406  SCFree(keys[0]);
2407  SCFree(keys[1]);
2408  return 0;
2409  }
2410  return AFPSetFlowStorage(p, p->afp_v.v4_map_fd, keys[0], keys[1], AF_INET);
2411  }
2412  /* For IPv6 case we don't handle extended header in eBPF */
2413  if (PKT_IS_IPV6(p) &&
2414  ((IPV6_GET_NH(p) == IPPROTO_TCP) || (IPV6_GET_NH(p) == IPPROTO_UDP))) {
2415  SCLogDebug("add an IPv6");
2416  if (p->afp_v.v6_map_fd == -1) {
2417  return 0;
2418  }
2419  int i;
2420  struct flowv6_keys *keys[2];
2421  keys[0] = SCCalloc(1, sizeof(struct flowv6_keys));
2422  if (keys[0] == NULL) {
2423  return 0;
2424  }
2425 
2426  for (i = 0; i < 4; i++) {
2427  keys[0]->src[i] = GET_IPV6_SRC_ADDR(p)[i];
2428  keys[0]->dst[i] = GET_IPV6_DST_ADDR(p)[i];
2429  }
2430  keys[0]->port16[0] = htons(GET_TCP_SRC_PORT(p));
2431  keys[0]->port16[1] = htons(GET_TCP_DST_PORT(p));
2432  keys[0]->vlan0 = p->vlan_id[0];
2433  keys[0]->vlan1 = p->vlan_id[1];
2434  keys[0]->vlan2 = p->vlan_id[2];
2435  if (IPV6_GET_NH(p) == IPPROTO_TCP) {
2436  keys[0]->ip_proto = 1;
2437  } else {
2438  keys[0]->ip_proto = 0;
2439  }
2440  if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[0],
2441  p->afp_v.nr_cpus) == 0) {
2442  LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2443  SCFree(keys[0]);
2444  return 0;
2445  }
2446  keys[1]= SCCalloc(1, sizeof(struct flowv6_keys));
2447  if (keys[1] == NULL) {
2448  EBPFDeleteKey(p->afp_v.v6_map_fd, keys[0]);
2449  LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2450  SCFree(keys[0]);
2451  return 0;
2452  }
2453  for (i = 0; i < 4; i++) {
2454  keys[1]->src[i] = GET_IPV6_DST_ADDR(p)[i];
2455  keys[1]->dst[i] = GET_IPV6_SRC_ADDR(p)[i];
2456  }
2457  keys[1]->port16[0] = htons(GET_TCP_DST_PORT(p));
2458  keys[1]->port16[1] = htons(GET_TCP_SRC_PORT(p));
2459  keys[1]->vlan0 = p->vlan_id[0];
2460  keys[1]->vlan1 = p->vlan_id[1];
2461  keys[1]->vlan2 = p->vlan_id[2];
2462  keys[1]->ip_proto = keys[0]->ip_proto;
2463  if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[1],
2464  p->afp_v.nr_cpus) == 0) {
2465  EBPFDeleteKey(p->afp_v.v6_map_fd, keys[0]);
2466  LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2467  SCFree(keys[0]);
2468  SCFree(keys[1]);
2469  return 0;
2470  }
2471  return AFPSetFlowStorage(p, p->afp_v.v6_map_fd, keys[0], keys[1], AF_INET6);
2472  }
2473  return 0;
2474 }
2475 
2476 bool g_flowv4_ok = true;
2477 bool g_flowv6_ok = true;
2478 
2479 #endif /* HAVE_PACKET_EBPF */
2480 
2481 /**
2482  * \brief Init function for ReceiveAFP.
2483  *
2484  * \param tv pointer to ThreadVars
2485  * \param initdata pointer to the interface passed from the user
2486  * \param data pointer gets populated with AFPThreadVars
2487  *
2488  * \todo Create a general AFP setup function.
2489  */
2490 TmEcode ReceiveAFPThreadInit(ThreadVars *tv, const void *initdata, void **data)
2491 {
2492  SCEnter();
2493  AFPIfaceConfig *afpconfig = (AFPIfaceConfig *)initdata;
2494 
2495  if (initdata == NULL) {
2496  SCLogError("initdata == NULL");
2498  }
2499 
2500  AFPThreadVars *ptv = SCMalloc(sizeof(AFPThreadVars));
2501  if (unlikely(ptv == NULL)) {
2502  afpconfig->DerefFunc(afpconfig);
2504  }
2505  memset(ptv, 0, sizeof(AFPThreadVars));
2506 
2507  ptv->tv = tv;
2508 
2509  strlcpy(ptv->iface, afpconfig->iface, AFP_IFACE_NAME_LENGTH);
2510  ptv->iface[AFP_IFACE_NAME_LENGTH - 1]= '\0';
2511 
2512  ptv->livedev = LiveGetDevice(ptv->iface);
2513  if (ptv->livedev == NULL) {
2514  SCLogError("Unable to find Live device");
2515  SCFree(ptv);
2517  }
2518 
2519  ptv->buffer_size = afpconfig->buffer_size;
2520  ptv->ring_size = afpconfig->ring_size;
2521  ptv->block_size = afpconfig->block_size;
2522  ptv->block_timeout = afpconfig->block_timeout;
2523 
2524  ptv->promisc = afpconfig->promisc;
2525  ptv->checksum_mode = afpconfig->checksum_mode;
2526  ptv->bpf_filter = NULL;
2527 
2528  ptv->threads = 1;
2529 #ifdef HAVE_PACKET_FANOUT
2531  ptv->cluster_id = 1;
2532  /* We only set cluster info if the number of reader threads is greater than 1 */
2533  if (afpconfig->threads > 1) {
2534  ptv->cluster_id = afpconfig->cluster_id;
2535  ptv->cluster_type = afpconfig->cluster_type;
2536  ptv->threads = afpconfig->threads;
2537  }
2538 #endif
2539  ptv->flags = afpconfig->flags;
2540 
2541  if (afpconfig->bpf_filter) {
2542  ptv->bpf_filter = afpconfig->bpf_filter;
2543  }
2544 #ifdef HAVE_PACKET_EBPF
2545  ptv->ebpf_lb_fd = afpconfig->ebpf_lb_fd;
2546  ptv->ebpf_filter_fd = afpconfig->ebpf_filter_fd;
2547  ptv->xdp_mode = afpconfig->xdp_mode;
2548  ptv->ebpf_t_config.cpus_count = UtilCpuGetNumProcessorsConfigured();
2549 
2550  if (ptv->flags & (AFP_BYPASS|AFP_XDPBYPASS)) {
2551  ptv->v4_map_fd = EBPFGetMapFDByName(ptv->iface, "flow_table_v4");
2552  if (ptv->v4_map_fd == -1) {
2553  if (g_flowv4_ok == false) {
2554  SCLogError("Can't find eBPF map fd for '%s'", "flow_table_v4");
2555  g_flowv4_ok = true;
2556  }
2557  }
2558  ptv->v6_map_fd = EBPFGetMapFDByName(ptv->iface, "flow_table_v6");
2559  if (ptv->v6_map_fd == -1) {
2560  if (g_flowv6_ok) {
2561  SCLogError("Can't find eBPF map fd for '%s'", "flow_table_v6");
2562  g_flowv6_ok = false;
2563  }
2564  }
2565  }
2566  ptv->ebpf_t_config = afpconfig->ebpf_t_config;
2567 #endif
2568 
2569 #ifdef PACKET_STATISTICS
2570  ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets",
2571  ptv->tv);
2572  ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops",
2573  ptv->tv);
2574  ptv->capture_errors = StatsRegisterCounter("capture.errors",
2575  ptv->tv);
2576 
2577  ptv->afpacket_spin = StatsRegisterAvgCounter("capture.afpacket.busy_loop_avg", ptv->tv);
2578 
2579  ptv->capture_afp_poll = StatsRegisterCounter("capture.afpacket.polls", ptv->tv);
2580  ptv->capture_afp_poll_signal = StatsRegisterCounter("capture.afpacket.poll_signal", ptv->tv);
2581  ptv->capture_afp_poll_timeout = StatsRegisterCounter("capture.afpacket.poll_timeout", ptv->tv);
2582  ptv->capture_afp_poll_data = StatsRegisterCounter("capture.afpacket.poll_data", ptv->tv);
2583  ptv->capture_afp_poll_err = StatsRegisterCounter("capture.afpacket.poll_errors", ptv->tv);
2584  ptv->capture_afp_send_err = StatsRegisterCounter("capture.afpacket.send_errors", ptv->tv);
2585 #endif
2586 
2587  ptv->copy_mode = afpconfig->copy_mode;
2588  if (ptv->copy_mode != AFP_COPY_MODE_NONE) {
2589  strlcpy(ptv->out_iface, afpconfig->out_iface, AFP_IFACE_NAME_LENGTH);
2590  ptv->out_iface[AFP_IFACE_NAME_LENGTH - 1]= '\0';
2591  /* Warn about BPF filter consequence */
2592  if (ptv->bpf_filter) {
2593  SCLogWarning("Enabling a BPF filter in IPS mode result"
2594  " in dropping all non matching packets.");
2595  }
2596  }
2597 
2598 
2599  if (AFPPeersListAdd(ptv) == TM_ECODE_FAILED) {
2600  SCFree(ptv);
2601  afpconfig->DerefFunc(afpconfig);
2603  }
2604 
2605  *data = (void *)ptv;
2606 
2607  afpconfig->DerefFunc(afpconfig);
2608 
2609  /* If kernel is older than 3.0, VLAN is not stripped so we don't
2610  * get the info from packet extended header but we will use a standard
2611  * parsing of packet data (See Linux commit bcc6d47903612c3861201cc3a866fb604f26b8b2) */
2612  if (SCKernelVersionIsAtLeast(3, 0)) {
2613  ptv->flags |= AFP_VLAN_IN_HEADER;
2614  }
2615 
2617 }
2618 
2619 /**
2620  * \brief This function prints stats to the screen at exit.
2621  * \param tv pointer to ThreadVars
2622  * \param data pointer that gets cast into AFPThreadVars for ptv
2623  */
2624 void ReceiveAFPThreadExitStats(ThreadVars *tv, void *data)
2625 {
2626  SCEnter();
2627  AFPThreadVars *ptv = (AFPThreadVars *)data;
2628 
2629 #ifdef PACKET_STATISTICS
2630  AFPDumpCounters(ptv);
2631  SCLogPerf("%s: (%s) kernel: Packets %" PRIu64 ", dropped %" PRIu64 "", ptv->iface, tv->name,
2634 #endif
2635 }
2636 
2637 /**
2638  * \brief DeInit function closes af packet socket at exit.
2639  * \param tv pointer to ThreadVars
2640  * \param data pointer that gets cast into AFPThreadVars for ptv
2641  */
2642 TmEcode ReceiveAFPThreadDeinit(ThreadVars *tv, void *data)
2643 {
2644  AFPThreadVars *ptv = (AFPThreadVars *)data;
2645 
2646  AFPSwitchState(ptv, AFP_STATE_DOWN);
2647 
2648 #ifdef HAVE_PACKET_XDP
2649  if ((ptv->ebpf_t_config.flags & EBPF_XDP_CODE) &&
2650  (!(ptv->ebpf_t_config.flags & EBPF_PINNED_MAPS))) {
2651  EBPFSetupXDP(ptv->iface, -1, ptv->xdp_mode);
2652  }
2653 #endif
2654 
2655  ptv->bpf_filter = NULL;
2656  if ((ptv->flags & AFP_TPACKET_V3) && ptv->ring.v3) {
2657  SCFree(ptv->ring.v3);
2658  } else {
2659  if (ptv->ring.v2)
2660  SCFree(ptv->ring.v2);
2661  }
2662 
2663  SCFree(ptv);
2665 }
2666 
2667 /** \internal
2668  * \brief add a VLAN header into the raw data for inspection, logging
2669  * and sending out in IPS mode
2670  *
2671  * The kernel doesn't provide the first VLAN header the raw packet data,
2672  * but instead feeds it to us through meta data. For logging and IPS
2673  * we need to put it back into the raw data. Luckily there is some head
2674  * room in the original data so its enough to move the ethernet header
2675  * a bit to make space for the VLAN header.
2676  */
2677 static void UpdateRawDataForVLANHdr(Packet *p)
2678 {
2679  if (p->afp_v.vlan_tci != 0) {
2680  uint8_t *pstart = GET_PKT_DATA(p) - VLAN_HEADER_LEN;
2681  size_t plen = GET_PKT_LEN(p) + VLAN_HEADER_LEN;
2682  /* move ethernet addresses */
2683  memmove(pstart, GET_PKT_DATA(p), 2 * ETH_ALEN);
2684  /* write vlan info */
2685  *(uint16_t *)(pstart + 2 * ETH_ALEN) = htons(0x8100);
2686  *(uint16_t *)(pstart + 2 * ETH_ALEN + 2) = htons(p->afp_v.vlan_tci);
2687 
2688  /* update the packet raw data pointer to start at the new offset */
2689  (void)PacketSetData(p, pstart, plen);
2690  /* update ethernet header pointer to point to the new start of the data */
2691  p->ethh = (void *)pstart;
2692  }
2693 }
2694 
2695 /**
2696  * \brief This function passes off to link type decoders.
2697  *
2698  * DecodeAFP decodes packets from AF_PACKET and passes
2699  * them off to the proper link type decoder.
2700  *
2701  * \param t pointer to ThreadVars
2702  * \param p pointer to the current packet
2703  * \param data pointer that gets cast into AFPThreadVars for ptv
2704  */
2705 TmEcode DecodeAFP(ThreadVars *tv, Packet *p, void *data)
2706 {
2707  SCEnter();
2708 
2709  const bool afp_vlan_hdr = p->vlan_idx != 0;
2711 
2713 
2714  /* update counters */
2716 
2717  /* call the decoder */
2718  DecodeLinkLayer(tv, dtv, p->datalink, p, GET_PKT_DATA(p), GET_PKT_LEN(p));
2719  /* post-decoding put vlan hdr back into the raw data) */
2720  if (afp_vlan_hdr) {
2722  UpdateRawDataForVLANHdr(p);
2723  }
2724 
2726 
2728 }
2729 
2730 TmEcode DecodeAFPThreadInit(ThreadVars *tv, const void *initdata, void **data)
2731 {
2732  SCEnter();
2734  if (dtv == NULL)
2736 
2738 
2739  *data = (void *)dtv;
2740 
2742 }
2743 
2744 TmEcode DecodeAFPThreadDeinit(ThreadVars *tv, void *data)
2745 {
2746  if (data != NULL)
2747  DecodeThreadVarsFree(tv, data);
2749 }
2750 
2751 #endif /* HAVE_AF_PACKET */
2752 /* eof */
2753 /**
2754  * @}
2755  */
TmModule_::cap_flags
uint8_t cap_flags
Definition: tm-modules.h:73
PacketCheckAction
bool PacketCheckAction(const Packet *p, const uint8_t a)
Definition: packet.c:48
bpf_program::bf_insns
struct bpf_insn * bf_insns
Definition: source-af-packet.c:82
PKT_IS_UDP
#define PKT_IS_UDP(p)
Definition: decode.h:248
AFPIfaceConfig_::promisc
int promisc
Definition: source-af-packet.h:97
tm-threads.h
max_pending_packets
uint16_t max_pending_packets
Definition: suricata.c:186
AFPThreadVars_::promisc
int promisc
Definition: source-af-packet.c:328
AFPIfaceConfig_::checksum_mode
ChecksumValidationMode checksum_mode
Definition: source-af-packet.h:101
PACKET_FANOUT_FLAG_DEFRAG
#define PACKET_FANOUT_FLAG_DEFRAG
Definition: source-af-packet.h:40
len
uint8_t len
Definition: app-layer-dnp3.h:2
peerslist
AFPPeersList peerslist
Definition: source-af-packet.c:446
AFPIfaceConfig_::xdp_mode
uint8_t xdp_mode
Definition: source-af-packet.h:109
GET_TCP_DST_PORT
#define GET_TCP_DST_PORT(p)
Definition: decode.h:217
AFPV_CLEANUP
#define AFPV_CLEANUP(afpv)
Definition: source-af-packet.h:172
AFP_BYPASS
#define AFP_BYPASS
Definition: source-af-packet.h:65
GET_TCP_SRC_PORT
#define GET_TCP_SRC_PORT(p)
Definition: decode.h:216
AFPThreadVars_::pkts
uint64_t pkts
Definition: source-af-packet.c:272
TP_STATUS_VLAN_VALID
#define TP_STATUS_VLAN_VALID
Definition: source-af-packet.c:193
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:167
AFPThreadVars_::checksum_mode
ChecksumValidationMode checksum_mode
Definition: source-af-packet.c:289
ThreadVars_::name
char name[16]
Definition: threadvars.h:64
PacketFreeOrRelease
void PacketFreeOrRelease(Packet *p)
Return a packet to where it was allocated.
Definition: decode.c:191
TAILQ_INIT
#define TAILQ_INIT(head)
Definition: queue.h:262
AFPPeer_::turn
int turn
Definition: source-af-packet.h:130
AFPThreadVars_::AFPRing::v2
union thdr ** v2
Definition: source-af-packet.c:267
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
Definition: util-atomic.h:315
AFPThreadVars_::send_errors_logged
uint64_t send_errors_logged
Definition: source-af-packet.c:303
AFP_COPY_MODE_NONE
#define AFP_COPY_MODE_NONE
Definition: source-af-packet.h:68
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1053
PKT_IS_IPV6
#define PKT_IS_IPV6(p)
Definition: decode.h:246
util-bpf.h
AFPThreadVars_::block_size
int block_size
Definition: source-af-packet.c:321
GetFlowBypassInfoID
FlowStorageId GetFlowBypassInfoID(void)
Definition: flow-util.c:217
FlowBypassInfo_
Definition: flow.h:520
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:387
AFPThreadVars_::afpacket_spin
uint16_t afpacket_spin
Definition: source-af-packet.c:295
AFPThreadVars_
Structure to hold thread specific variables.
Definition: source-af-packet.c:265
AFPPeer_::peer
struct AFPPeer_ * peer
Definition: source-af-packet.h:132
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
TmThreadsSetFlag
void TmThreadsSetFlag(ThreadVars *tv, uint32_t flag)
Set a thread flag.
Definition: tm-threads.c:99
AFP_READ_OK
@ AFP_READ_OK
Definition: source-af-packet.c:235
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
AFPIfaceConfig_::ebpf_filter_fd
int ebpf_filter_fd
Definition: source-af-packet.h:106
util-checksum.h
AFPThreadVars_::AFPTpacketReq
Definition: source-af-packet.c:340
AFPThreadVars_::block_timeout
int block_timeout
Definition: source-af-packet.c:322
action-globals.h
Packet_::flags
uint32_t flags
Definition: decode.h:467
threads.h
thdr::raw
void * raw
Definition: source-af-packet.c:252
Packet_::vlan_idx
uint8_t vlan_idx
Definition: decode.h:458
AFPThreadVars_::buffer_size
int buffer_size
Definition: source-af-packet.c:324
UtilCpuGetNumProcessorsConfigured
uint16_t UtilCpuGetNumProcessorsConfigured(void)
Get the number of cpus configured in the system.
Definition: util-cpu.c:59
AFP_SOCK_PROTECT
#define AFP_SOCK_PROTECT
Definition: source-af-packet.h:60
PACKET_FANOUT_HASH
#define PACKET_FANOUT_HASH
Definition: source-af-packet.h:32
AFP_KERNEL_DROP
@ AFP_KERNEL_DROP
Definition: source-af-packet.c:239
LiveDevice_
Definition: util-device.h:49
AFPPeersListInit
TmEcode AFPPeersListInit(void)
Init the global list of AFPPeer.
Definition: source-af-packet.c:452
AFPThreadVars
struct AFPThreadVars_ AFPThreadVars
Structure to hold thread specific variables.
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:333
AFP_DOWN_COUNTER_INTERVAL
#define AFP_DOWN_COUNTER_INTERVAL
Definition: source-af-packet.c:172
AFPThreadVars_::ring_size
int ring_size
Definition: source-af-packet.c:320
AFPThreadVars_::capture_afp_send_err
uint16_t capture_afp_send_err
Definition: source-af-packet.c:301
THV_RUNNING
#define THV_RUNNING
Definition: threadvars.h:54
AFPIfaceConfig_::threads
int threads
Definition: source-af-packet.h:84
packet-queue.h
AFPIfaceConfig_::ring_size
int ring_size
Definition: source-af-packet.h:88
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
TmModuleDecodeAFPRegister
void TmModuleDecodeAFPRegister(void)
Registration Function for DecodeAFP.
Definition: source-af-packet.c:603
AFPIfaceConfig_::block_timeout
int block_timeout
Definition: source-af-packet.h:92
SCKernelVersionIsAtLeast
int SCKernelVersionIsAtLeast(int major, int minor)
Definition: util-host-info.c:37
AFPThreadVars_::ring
union AFPThreadVars_::AFPRing ring
tm-threads-common.h
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
MIN
#define MIN(x, y)
Definition: suricata-common.h:386
tm-modules.h
util-privs.h
AFP_PEERS_MAX_TRY
#define AFP_PEERS_MAX_TRY
StatsSyncCountersIfSignalled
#define StatsSyncCountersIfSignalled(tv)
Definition: counters.h:141
CHECKSUM_VALIDATION_DISABLE
@ CHECKSUM_VALIDATION_DISABLE
Definition: decode.h:45
AFP_IFACE_NAME_LENGTH
#define AFP_IFACE_NAME_LENGTH
Definition: source-af-packet.c:166
AFPIfaceConfig_::out_iface
const char * out_iface
Definition: source-af-packet.h:110
CHECKSUM_VALIDATION_KERNEL
@ CHECKSUM_VALIDATION_KERNEL
Definition: decode.h:49
TAILQ_INSERT_TAIL
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:294
AFP_XDPBYPASS
#define AFP_XDPBYPASS
Definition: source-af-packet.h:66
PacketDecodeFinalize
void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Finalize decoding of a packet.
Definition: decode.c:147
AFPIfaceConfig_::flags
unsigned int flags
Definition: source-af-packet.h:99
AFPThreadVars_::capture_kernel_drops
uint16_t capture_kernel_drops
Definition: source-af-packet.c:293
AFPThreadVars_::ring_buf
uint8_t * ring_buf
Definition: source-af-packet.c:353
AFP_READ_FAILURE
@ AFP_READ_FAILURE
Definition: source-af-packet.c:236
AFP_STATE_UP
#define AFP_STATE_UP
Definition: source-af-packet.c:169
Packet_::BypassPacketsFlow
int(* BypassPacketsFlow)(struct Packet_ *)
Definition: decode.h:522
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:85
AFPPeersListClean
void AFPPeersListClean(void)
Clean the global peers list.
Definition: source-af-packet.c:585
AFPGetLinkType
int AFPGetLinkType(const char *ifname)
Definition: source-af-packet.c:1533
GET_IPV6_DST_ADDR
#define GET_IPV6_DST_ADDR(p)
Definition: decode.h:215
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
tmqh-packetpool.h
AFPPeer_::sock_protect
SCMutex sock_protect
Definition: source-af-packet.h:129
AFPPeersListCheck
TmEcode AFPPeersListCheck(void)
Check that all AFPPeer got a peer.
Definition: source-af-packet.c:469
TmModule_::PktAcqLoop
TmEcode(* PktAcqLoop)(ThreadVars *, void *, void *)
Definition: tm-modules.h:54
AFP_PEERS_WAIT
#define AFP_PEERS_WAIT
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:84
AFPPeersList
struct AFPPeersList_ AFPPeersList
AFP_BLOCK_SIZE_DEFAULT_ORDER
#define AFP_BLOCK_SIZE_DEFAULT_ORDER
Definition: source-af-packet.h:78
AFPIfaceConfig_::cluster_type
int cluster_type
Definition: source-af-packet.h:95
AFPIfaceConfig_::cluster_id
uint16_t cluster_id
Definition: source-af-packet.h:94
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
TmModule_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
Packet_::datalink
int datalink
Definition: decode.h:611
AFPThreadVars_::socket
int socket
Definition: source-af-packet.c:318
AFP_VLAN_IN_HEADER
#define AFP_VLAN_IN_HEADER
Definition: source-af-packet.h:63
AFPIfaceConfig_::block_size
int block_size
Definition: source-af-packet.h:90
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1056
CHECKSUM_VALIDATION_ENABLE
@ CHECKSUM_VALIDATION_ENABLE
Definition: decode.h:46
PKT_IS_TCP
#define PKT_IS_TCP(p)
Definition: decode.h:247
AFPPeersList_
Definition: source-af-packet.c:411
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:525
CHECKSUM_VALIDATION_AUTO
@ CHECKSUM_VALIDATION_AUTO
Definition: decode.h:47
AFPThreadVars_::frame_offset
unsigned int frame_offset
Definition: source-af-packet.c:287
GetIfaceMaxPacketSize
int GetIfaceMaxPacketSize(LiveDevice *ld)
output max packet size for a link
Definition: util-ioctl.c:120
IPV4_GET_IPPROTO
#define IPV4_GET_IPPROTO(p)
Definition: decode-ipv4.h:148
TAILQ_REMOVE
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:312
decode.h
TMM_DECODEAFP
@ TMM_DECODEAFP
Definition: tm-threads-common.h:56
util-device.h
util-debug.h
PKT_SRC_WIRE
@ PKT_SRC_WIRE
Definition: decode.h:54
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:250
AFPIfaceConfig_::ebpf_lb_fd
int ebpf_lb_fd
Definition: source-af-packet.h:104
AFP_FATAL_ERROR
@ AFP_FATAL_ERROR
Definition: source-af-packet.c:243
util-error.h
AFPThreadVars_::datalink
uint32_t datalink
Definition: source-af-packet.c:278
VLAN_HEADER_LEN
#define VLAN_HEADER_LEN
Definition: decode-vlan.h:46
TmModule_::PktAcqBreakLoop
TmEcode(* PktAcqBreakLoop)(ThreadVars *, void *)
Definition: tm-modules.h:57
FlowBypassInfo_::BypassUpdate
bool(* BypassUpdate)(Flow *f, void *data, time_t tsec)
Definition: flow.h:521
TP_STATUS_CSUMNOTREADY
#define TP_STATUS_CSUMNOTREADY
Definition: source-af-packet.c:190
AFP_MMAP_LOCKED
#define AFP_MMAP_LOCKED
Definition: source-af-packet.h:64
AFPThreadVars_::capture_afp_poll_data
uint16_t capture_afp_poll_data
Definition: source-af-packet.c:299
util-cpu.h
FlowBypassInfo_::BypassFree
void(* BypassFree)(void *data)
Definition: flow.h:522
Packet_::ts
SCTime_t ts
Definition: decode.h:475
BIT_U32
#define BIT_U32(n)
Definition: suricata-common.h:395
TmModuleReceiveAFPRegister
void TmModuleReceiveAFPRegister(void)
Registration Function for RecieveAFP.
Definition: source-af-packet.c:384
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
PACKET_FANOUT_LB
#define PACKET_FANOUT_LB
Definition: source-af-packet.h:33
SCTime_t::secs
uint64_t secs
Definition: util-time.h:41
LiveGetDevice
LiveDevice * LiveGetDevice(const char *name)
Get a pointer to the device at idx.
Definition: util-device.c:248
TP_STATUS_USER
#define TP_STATUS_USER
Definition: source-af-packet.c:181
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
GET_PKT_DATA
#define GET_PKT_DATA(p)
Definition: decode.h:220
AFPThreadVars_::threads
int threads
Definition: source-af-packet.c:338
util-ebpf.h
Packet_::ethh
EthernetHdr * ethh
Definition: decode.h:528
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
TmModule_::Func
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition: tm-modules.h:52
Packet_::sp
Port sp
Definition: decode.h:437
AFPThreadVars_::ring_buflen
unsigned int ring_buflen
Definition: source-af-packet.c:352
LiveDevice_::dev
char * dev
Definition: util-device.h:50
FlowBypassInfo_::bypass_data
void * bypass_data
Definition: flow.h:523
AFPIfaceConfig_::DerefFunc
void(* DerefFunc)(void *)
Definition: source-af-packet.h:115
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
AFPThreadVars_::afp_state
uint8_t afp_state
Definition: source-af-packet.c:306
IPV6_GET_NH
#define IPV6_GET_NH(p)
Definition: decode-ipv6.h:86
TP_STATUS_USER_BUSY
#define TP_STATUS_USER_BUSY
Definition: source-af-packet.c:227
AFPThreadVars_::iface
char iface[AFP_IFACE_NAME_LENGTH]
Definition: source-af-packet.c:347
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:295
AFP_STATE_DOWN
#define AFP_STATE_DOWN
Definition: source-af-packet.c:168
SC_ATOMIC_SUB
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
Definition: util-atomic.h:342
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:1260
SC_ATOMIC_DECLARE
#define SC_ATOMIC_DECLARE(type, name)
wrapper for declaring atomic variables.
Definition: util-atomic.h:281
PacketPoolWait
void PacketPoolWait(void)
Definition: tmqh-packetpool.c:69
AFPThreadVars_::AFPRing::v3
struct iovec * v3
Definition: source-af-packet.c:268
Packet_
Definition: decode.h:430
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:219
AFPPeer_::flags
int flags
Definition: source-af-packet.h:128
conf.h
TmSlot_
Definition: tm-threads.h:53
PKT_IGNORE_CHECKSUM
#define PKT_IGNORE_CHECKSUM
Definition: decode.h:1016
SCTime_t
Definition: util-time.h:40
Packet_::livedev
struct LiveDevice_ * livedev
Definition: decode.h:590
TmEcode
TmEcode
Definition: tm-threads-common.h:83
IS_TUNNEL_PKT
#define IS_TUNNEL_PKT(p)
Definition: decode.h:794
util-host-info.h
LiveDevice_::mtu
int mtu
Definition: util-device.h:52
TmModule_::name
const char * name
Definition: tm-modules.h:44
AFPThreadVars_::pkttype_filter_mask
uint32_t pkttype_filter_mask
Definition: source-af-packet.c:331
AFPThreadVars_::capture_afp_poll_timeout
uint16_t capture_afp_poll_timeout
Definition: source-af-packet.c:298
LiveDevAddBypassStats
void LiveDevAddBypassStats(LiveDevice *dev, uint64_t cnt, int family)
Definition: util-device.c:515
DecodeThreadVars_::counter_vlan
uint16_t counter_vlan
Definition: decode.h:704
AFP_SURI_FAILURE
@ AFP_SURI_FAILURE
Definition: source-af-packet.c:238
runmodes.h
LiveDevAddBypassSuccess
void LiveDevAddBypassSuccess(LiveDevice *dev, uint64_t cnt, int family)
Definition: util-device.c:572
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:224
FlowGetStorageById
void * FlowGetStorageById(const Flow *f, FlowStorageId id)
Definition: flow-storage.c:40
SCMutexInit
#define SCMutexInit(mut, mutattrs)
Definition: threads-debug.h:116
TM_FLAG_RECEIVE_TM
#define TM_FLAG_RECEIVE_TM
Definition: tm-modules.h:31
AFP_NEED_PEER
#define AFP_NEED_PEER
Definition: source-af-packet.h:58
AFPThreadVars_::down_count
int down_count
Definition: source-af-packet.c:333
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
AFPThreadVars_::cluster_type
int cluster_type
Definition: source-af-packet.c:336
AFPThreadVars_::livedev
LiveDevice * livedev
Definition: source-af-packet.c:276
default_packet_size
uint32_t default_packet_size
Definition: decode.c:72
LINKTYPE_RAW
#define LINKTYPE_RAW
Definition: decode.h:972
tm-queuehandlers.h
AFPThreadVars_::cluster_id
uint16_t cluster_id
Definition: source-af-packet.c:335
AFPThreadVars_::slot
TmSlot * slot
Definition: source-af-packet.c:275
Packet_::ReleasePacket
void(* ReleasePacket)(struct Packet_ *)
Definition: decode.h:519
flow-storage.h
TMM_RECEIVEAFP
@ TMM_RECEIVEAFP
Definition: tm-threads-common.h:54
Packet_::flow
struct Flow_ * flow
Definition: decode.h:469
AFPThreadVars_::capture_afp_poll_signal
uint16_t capture_afp_poll_signal
Definition: source-af-packet.c:297
AFPPeer_
Definition: source-af-packet.h:123
DecodeThreadVarsFree
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:707
AFPThreadVars_::capture_afp_poll_err
uint16_t capture_afp_poll_err
Definition: source-af-packet.c:300
ChecksumValidationMode
ChecksumValidationMode
Definition: decode.h:44
AFP_RECOVERABLE_ERROR
@ AFP_RECOVERABLE_ERROR
Definition: source-af-packet.c:244
suricata-common.h
packet.h
AFPThreadVars_::flags
unsigned int flags
Definition: source-af-packet.c:308
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
SCLogPerf
#define SCLogPerf(...)
Definition: util-debug.h:230
version
uint8_t version
Definition: decode-gre.h:1
SCBPFFree
void SCBPFFree(struct bpf_program *program)
Definition: util-bpf.c:56
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
thdr::h2
struct tpacket2_hdr * h2
Definition: source-af-packet.c:248
AFP_TPACKET_V3
#define AFP_TPACKET_V3
Definition: source-af-packet.h:62
LiveDevAddBypassFail
void LiveDevAddBypassFail(LiveDevice *dev, uint64_t cnt, int family)
Definition: util-device.c:553
FatalError
#define FatalError(...)
Definition: util-debug.h:502
thdr
Definition: source-af-packet.c:247
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
util-optimize.h
TmModule_::ThreadExitPrintStats
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:48
threadvars.h
util-validate.h
source-af-packet.h
StatsAddUI64
void StatsAddUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Adds a value of type uint64_t to the local counter.
Definition: counters.c:146
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
FRAME_BUSY
#define FRAME_BUSY(tp_status)
Definition: source-af-packet.c:231
POLL_TIMEOUT
#define POLL_TIMEOUT
Definition: source-af-packet.c:174
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
GET_IPV6_SRC_ADDR
#define GET_IPV6_SRC_ADDR(p)
Definition: decode.h:214
SCFree
#define SCFree(p)
Definition: util-mem.h:61
AFP_COPY_MODE_IPS
#define AFP_COPY_MODE_IPS
Definition: source-af-packet.h:70
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:668
AFPThreadVars_::tv
ThreadVars * tv
Definition: source-af-packet.c:274
AFPIfaceConfig_::buffer_size
int buffer_size
Definition: source-af-packet.h:86
AFPThreadVars_::req
union AFPThreadVars_::AFPTpacketReq req
bpf_program
Definition: source-af-packet.c:80
util-ioctl.h
AFP_RECONNECT_TIMEOUT
#define AFP_RECONNECT_TIMEOUT
Definition: source-af-packet.c:171
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:688
TAILQ_HEAD
#define TAILQ_HEAD(name, type)
Definition: queue.h:230
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:727
AFPThreadVars_::out_iface
char out_iface[AFP_IFACE_NAME_LENGTH]
Definition: source-af-packet.c:349
TP_STATUS_KERNEL
#define TP_STATUS_KERNEL
Definition: source-af-packet.c:178
AFPIfaceConfig_::iface
char iface[AFP_IFACE_NAME_LENGTH]
Definition: source-af-packet.h:82
SCBPFCompile
int SCBPFCompile(int snaplen_arg, int linktype_arg, struct bpf_program *program, const char *buf, int optimize, uint32_t mask, char *errbuf, size_t errbuf_len)
Definition: util-bpf.c:62
suricata.h
Packet_::dst
Address dst
Definition: decode.h:435
AFPThreadVars_::copy_mode
uint8_t copy_mode
Definition: source-af-packet.c:307
AFPIfaceConfig_::copy_mode
uint8_t copy_mode
Definition: source-af-packet.h:100
Packet_::vlan_id
uint16_t vlan_id[VLAN_MAX_LAYERS]
Definition: decode.h:457
TmSlot_::slot_next
struct TmSlot_ * slot_next
Definition: tm-threads.h:62
AFPIfaceConfig_
Definition: source-af-packet.h:81
AFPIfaceConfig_::bpf_filter
const char * bpf_filter
Definition: source-af-packet.h:102
bpf_program::bf_len
unsigned int bf_len
Definition: source-af-packet.c:81
StatsRegisterAvgCounter
uint16_t StatsRegisterAvgCounter(const char *name, struct ThreadVars_ *tv)
Registers a counter, whose value holds the average of all the values assigned to it.
Definition: counters.c:981
GET_IPV4_SRC_ADDR_U32
#define GET_IPV4_SRC_ADDR_U32(p)
Definition: decode.h:207
PACKET_FANOUT
#define PACKET_FANOUT
Definition: source-af-packet.h:30
AFPThreadVars_::AFPRing
Definition: source-af-packet.c:266
GET_IPV4_DST_ADDR_U32
#define GET_IPV4_DST_ADDR_U32(p)
Definition: decode.h:208
AFPPeer_::iface
char iface[AFP_IFACE_NAME_LENGTH]
Definition: source-af-packet.h:134
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:376
AFPThreadVars_::capture_kernel_packets
uint16_t capture_kernel_packets
Definition: source-af-packet.c:292
Packet_::dp
Port dp
Definition: decode.h:445
StatsRegisterCounter
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:961
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
SCMutexDestroy
#define SCMutexDestroy
Definition: threads-debug.h:120
AFPThreadVars_::capture_errors
uint16_t capture_errors
Definition: source-af-packet.c:294
AFPThreadVars_::AFPTpacketReq::v2
struct tpacket_req v2
Definition: source-af-packet.c:341
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:245
AFPThreadVars_::bpf_filter
const char * bpf_filter
Definition: source-af-packet.c:326
AFPThreadVars_::mpeer
AFPPeer * mpeer
Definition: source-af-packet.c:311
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:208
SC_CAP_NET_RAW
#define SC_CAP_NET_RAW
Definition: util-privs.h:32
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:104
Packet_::src
Address src
Definition: decode.h:434
TP_STATUS_LOSING
#define TP_STATUS_LOSING
Definition: source-af-packet.c:187
TmModule_::flags
uint8_t flags
Definition: tm-modules.h:76
AFPIsFanoutSupported
int AFPIsFanoutSupported(uint16_t cluster_id)
test if we can use FANOUT. Older kernels like those in CentOS6 have HAVE_PACKET_FANOUT defined but fa...
Definition: source-af-packet.c:1812
DecodeUpdatePacketCounters
void DecodeUpdatePacketCounters(ThreadVars *tv, const DecodeThreadVars *dtv, const Packet *p)
Definition: decode.c:654
AFPThreadVars_::capture_afp_poll
uint16_t capture_afp_poll
Definition: source-af-packet.c:296
LINKTYPE_ETHERNET
#define LINKTYPE_ETHERNET
Definition: decode.h:969
suricata_ctl_flags
volatile uint8_t suricata_ctl_flags
Definition: suricata.c:172
AFP_EMERGENCY_MODE
#define AFP_EMERGENCY_MODE
Definition: source-af-packet.h:61