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