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