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