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