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