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