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