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