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