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