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