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