1 /* Copyright (C) 2011-2018 Open Information Security Foundation
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
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.
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
19 * \defgroup afppacket AF_PACKET running mode
27 * \author Eric Leblond <eric@regit.org>
29 * AF_PACKET socket acquisition support
33 #define PCAP_DONT_INCLUDE_PCAP_BPF_H 1
34 #define SC_PCAP_DONT_INCLUDE_PCAP_H 1
35 #include "suricata-common.h"
39 #include "packet-queue.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"
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"
60 #include "flow-storage.h"
65 #include <sys/ioctl.h>
68 #ifdef HAVE_PACKET_EBPF
69 #include "util-ebpf.h"
70 #include <bpf/libbpf.h>
76 struct bpf_insn
*bf_insns
;
83 #ifdef HAVE_PCAP_PCAP_H
84 #include <pcap/pcap.h>
89 #if HAVE_LINUX_IF_ETHER_H
90 #include <linux/if_ether.h>
93 #if HAVE_LINUX_IF_PACKET_H
94 #include <linux/if_packet.h>
97 #if HAVE_LINUX_IF_ARP_H
98 #include <linux/if_arp.h>
101 #if HAVE_LINUX_FILTER_H
102 #include <linux/filter.h>
106 #include <sys/mman.h>
109 #ifdef HAVE_HW_TIMESTAMPING
110 #include <linux/net_tstamp.h>
113 #endif /* HAVE_AF_PACKET */
115 extern int max_pending_packets
;
117 #ifndef HAVE_AF_PACKET
119 TmEcode
NoAFPSupportExit(ThreadVars
*, const void *, void **);
121 void TmModuleReceiveAFPRegister (void)
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
;
134 * \brief Registration Function for DecodeAFP.
136 void TmModuleDecodeAFPRegister (void)
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
;
149 * \brief this function prints an error message and exits.
151 TmEcode
NoAFPSupportExit(ThreadVars
*tv
, const void *initdata
, void **data
)
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
);
159 #else /* We have AF_PACKET support */
161 #define AFP_IFACE_NAME_LENGTH 48
163 #define AFP_STATE_DOWN 0
164 #define AFP_STATE_UP 1
166 #define AFP_RECONNECT_TIMEOUT 500000
167 #define AFP_DOWN_COUNTER_INTERVAL 40
169 #define POLL_TIMEOUT 100
171 #ifndef TP_STATUS_USER_BUSY
172 /* for new use latest bit available in tp_status */
173 #define TP_STATUS_USER_BUSY (1 << 31)
176 #ifndef TP_STATUS_VLAN_VALID
177 #define TP_STATUS_VLAN_VALID (1 << 4)
183 /** Error during treatment by other functions of Suricata */
190 AFP_RECOVERABLE_ERROR
,
194 struct tpacket2_hdr
*h2
;
195 #ifdef HAVE_TPACKET_V3
196 struct tpacket3_hdr
*h3
;
201 static int AFPBypassCallback(Packet
*p
);
202 static int AFPXDPBypassCallback(Packet
*p
);
206 * \brief Structure to hold thread specific variables.
208 typedef struct AFPThreadVars_
221 /* data link type for the thread */
224 #ifdef HAVE_PACKET_EBPF
225 /* File descriptor of the IPv4 flow bypass table maps */
227 /* File descriptor of the IPv6 flow bypass table maps */
231 unsigned int frame_offset
;
233 ChecksumValidationMode checksum_mode
;
235 /* references to packet and drop counters */
236 uint16_t capture_kernel_packets
;
237 uint16_t capture_kernel_drops
;
238 uint16_t capture_errors
;
249 uint8_t *data
; /** Per function and thread data */
250 int datalen
; /** Length of per function and thread data */
254 * Init related members
257 /* thread specific socket */
263 /* socket buffer size */
266 const char *bpf_filter
;
279 union AFPTpacketReq
{
280 struct tpacket_req v2
;
281 #ifdef HAVE_TPACKET_V3
282 struct tpacket_req3 v3
;
286 char iface
[AFP_IFACE_NAME_LENGTH
];
287 /* IPS output iface */
288 char out_iface
[AFP_IFACE_NAME_LENGTH
];
290 /* mmap'ed ring buffer */
291 unsigned int ring_buflen
;
296 #ifdef HAVE_PACKET_EBPF
297 struct ebpf_timeout_config ebpf_t_config
;
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
);
308 TmEcode
DecodeAFPThreadInit(ThreadVars
*, const void *, void **);
309 TmEcode
DecodeAFPThreadDeinit(ThreadVars
*tv
, void *data
);
310 TmEcode
DecodeAFP(ThreadVars
*, Packet
*, void *, PacketQueue
*, PacketQueue
*);
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
);
320 * \brief Registration Function for RecieveAFP.
321 * \todo Unit tests are needed for this module.
323 void TmModuleReceiveAFPRegister (void)
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
;
340 * \defgroup afppeers AFP peers list
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.
352 typedef struct AFPPeersList_
{
353 TAILQ_HEAD(, AFPPeer_
) peers
; /**< Head of list of fragments. */
356 int turn
; /**< Next value for initialisation order */
357 SC_ATOMIC_DECLARE(int, reached
); /**< Counter used to synchronize start */
361 * \brief Update the peer.
363 * Update the AFPPeer of a thread ie set new state, socket number
367 static void AFPPeerUpdate(AFPThreadVars
*ptv
)
369 if (ptv
->mpeer
== NULL
) {
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
);
378 * \brief Clean and free ressource used by an ::AFPPeer
380 static void AFPPeerClean(AFPPeer
*peer
)
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
);
390 AFPPeersList peerslist
;
394 * \brief Init the global list of ::AFPPeer
396 TmEcode
AFPPeersListInit()
399 TAILQ_INIT(&peerslist
.peers
);
400 peerslist
.peered
= 0;
403 SC_ATOMIC_INIT(peerslist
.reached
);
404 (void) SC_ATOMIC_SET(peerslist
.reached
, 0);
405 SCReturnInt(TM_ECODE_OK
);
409 * \brief Check that all ::AFPPeer got a peer
411 * \retval TM_ECODE_FAILED if some threads are not peered or TM_ECODE_OK else.
413 TmEcode
AFPPeersListCheck()
415 #define AFP_PEERS_MAX_TRY 4
416 #define AFP_PEERS_WAIT 20000
419 while (try < AFP_PEERS_MAX_TRY
) {
420 if (peerslist
.cnt
!= peerslist
.peered
) {
421 usleep(AFP_PEERS_WAIT
);
423 SCReturnInt(TM_ECODE_OK
);
427 SCLogError(SC_ERR_AFP_CREATE
, "Threads number not equals");
428 SCReturnInt(TM_ECODE_FAILED
);
432 * \brief Declare a new AFP thread to AFP peers list.
434 static TmEcode
AFPPeersListAdd(AFPThreadVars
*ptv
)
437 AFPPeer
*peer
= SCMalloc(sizeof(AFPPeer
));
441 if (unlikely(peer
== NULL
)) {
442 SCReturnInt(TM_ECODE_FAILED
);
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
++;
452 if (peer
->flags
& AFP_SOCK_PROTECT
) {
453 SCMutexInit(&peer
->sock_protect
, NULL
);
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
);
460 /* add element to iface list */
461 TAILQ_INSERT_TAIL(&peerslist
.peers
, peer
, next
);
463 if (ptv
->copy_mode
!= AFP_COPY_MODE_NONE
) {
466 /* Iter to find a peer */
467 TAILQ_FOREACH(pitem
, &peerslist
.peers
, next
) {
470 if (strcmp(pitem
->iface
, ptv
->out_iface
))
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.",
481 ptv
->out_iface
, out_mtu
,
482 (out_mtu
> mtu
) ? mtu
: out_mtu
);
484 peerslist
.peered
+= 2;
491 SCReturnInt(TM_ECODE_OK
);
494 static int AFPPeersListWaitTurn(AFPPeer
*peer
)
496 /* If turn is zero, we already have started threads once */
497 if (peerslist
.turn
== 0)
500 if (peer
->turn
== SC_ATOMIC_GET(peerslist
.reached
))
505 static void AFPPeersListReachedInc(void)
507 if (peerslist
.turn
== 0)
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
520 static int AFPPeersListStarted(void)
522 return !peerslist
.turn
;
526 * \brief Clean the global peers list.
528 void AFPPeersListClean()
532 while ((pitem
= TAILQ_FIRST(&peerslist
.peers
))) {
533 TAILQ_REMOVE(&peerslist
.peers
, pitem
, next
);
543 * \brief Registration Function for DecodeAFP.
544 * \todo Unit tests are needed for this module.
546 void TmModuleDecodeAFPRegister (void)
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
;
559 static int AFPCreateSocket(AFPThreadVars
*ptv
, char *devname
, int verbose
);
561 static inline void AFPDumpCounters(AFPThreadVars
*ptv
)
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
"",
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
);
580 * \brief AF packet read function.
582 * This function fills
583 * From here the packets are picked up by the DecodeAFP thread.
585 * \param user pointer to AFPThreadVars
586 * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
588 static int AFPRead(AFPThreadVars
*ptv
)
591 /* XXX should try to use read that get directly to packet */
594 struct sockaddr_ll from
;
597 struct cmsghdr
*cmsg
;
600 char buf
[CMSG_SPACE(sizeof(struct tpacket_auxdata
))];
602 unsigned char aux_checksum
= 0;
604 msg
.msg_name
= &from
;
605 msg
.msg_namelen
= sizeof(from
);
608 msg
.msg_control
= &cmsg_buf
;
609 msg
.msg_controllen
= sizeof(cmsg_buf
);
613 offset
= SLL_HEADER_LEN
;
616 iov
.iov_len
= ptv
->datalen
- offset
;
617 iov
.iov_base
= ptv
->data
+ offset
;
619 caplen
= recvmsg(ptv
->socket
, &msg
, MSG_TRUNC
);
622 SCLogWarning(SC_ERR_AFP_READ
, "recvmsg failed with error code %" PRId32
,
624 SCReturnInt(AFP_READ_FAILURE
);
627 p
= PacketGetFromQueueOrAlloc();
629 SCReturnInt(AFP_SURI_FAILURE
);
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
;
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
;
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
,
653 TmqhOutputPacketpool(ptv
->tv
, p
);
654 SCReturnInt(AFP_READ_FAILURE
);
658 p
->livedev
= ptv
->livedev
;
660 /* add forged header */
662 SllHdr
* hdrp
= (SllHdr
*)ptv
->data
;
663 /* XXX this is minimalist, but this seems enough */
664 hdrp
->sll_protocol
= from
.sll_protocol
;
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
);
673 SCLogDebug("pktlen: %" PRIu32
" (pkt %p, pkt data %p)",
674 GET_PKT_LEN(p
), p
, GET_PKT_DATA(p
));
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
;
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
;
696 if (cmsg
->cmsg_len
< CMSG_LEN(sizeof(struct tpacket_auxdata
)) ||
697 cmsg
->cmsg_level
!= SOL_PACKET
||
698 cmsg
->cmsg_type
!= PACKET_AUXDATA
)
701 aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
703 if (aux_checksum
&& (aux
->tp_status
& TP_STATUS_CSUMNOTREADY
)) {
704 p
->flags
|= PKT_IGNORE_CHECKSUM
;
709 if (TmThreadsSlotProcessPkt(ptv
->tv
, ptv
->slot
, p
) != TM_ECODE_OK
) {
710 TmqhOutputPacketpool(ptv
->tv
, p
);
711 SCReturnInt(AFP_SURI_FAILURE
);
713 SCReturnInt(AFP_READ_OK
);
717 * \brief AF packet write function.
719 * This function has to be called before the memory
720 * related to Packet in ring buffer is released.
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
727 static TmEcode
AFPWritePacket(Packet
*p
, int version
)
729 struct sockaddr_ll socket_address
;
734 uint16_t vlan_tci
= 0;
736 if (p
->afp_v
.copy_mode
== AFP_COPY_MODE_IPS
) {
737 if (PACKET_TEST_ACTION(p
, ACTION_DROP
)) {
742 if (SC_ATOMIC_GET(p
->afp_v
.peer
->state
) == AFP_STATE_DOWN
)
745 if (p
->ethh
== NULL
) {
746 SCLogWarning(SC_ERR_INVALID_VALUE
, "Should have an Ethernet header");
747 return TM_ECODE_FAILED
;
749 /* Index of the network device */
750 socket_address
.sll_ifindex
= SC_ATOMIC_GET(p
->afp_v
.peer
->if_idx
);
752 socket_address
.sll_halen
= ETH_ALEN
;
753 /* Destination MAC */
754 memcpy(socket_address
.sll_addr
, p
->ethh
, 6);
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
);
761 h
.raw
= p
->afp_v
.relptr
;
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
;
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
;
776 /* Should not get here */
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
);
790 pstart
= GET_PKT_DATA(p
);
791 plen
= GET_PKT_LEN(p
);
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",
800 if (p
->afp_v
.peer
->flags
& AFP_SOCK_PROTECT
)
801 SCMutexUnlock(&p
->afp_v
.peer
->sock_protect
);
802 return TM_ECODE_FAILED
;
804 if (p
->afp_v
.peer
->flags
& AFP_SOCK_PROTECT
)
805 SCMutexUnlock(&p
->afp_v
.peer
->sock_protect
);
810 static void AFPReleaseDataFromRing(Packet
*p
)
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
);
818 if (AFPDerefSocket(p
->afp_v
.mpeer
) == 0)
821 if (p
->afp_v
.relptr
) {
823 h
.raw
= p
->afp_v
.relptr
;
824 h
.h2
->tp_status
= TP_STATUS_KERNEL
;
828 AFPV_CLEANUP(&p
->afp_v
);
831 #ifdef HAVE_TPACKET_V3
832 static void AFPReleasePacketV3(Packet
*p
)
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
);
839 PacketFreeOrRelease(p
);
843 static void AFPReleasePacket(Packet
*p
)
845 AFPReleaseDataFromRing(p
);
846 PacketFreeOrRelease(p
);
850 * \brief AF packet read function for ring
852 * This function fills
853 * From here the packets are picked up by the DecodeAFP thread.
855 * \param user pointer to AFPThreadVars
856 * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
858 static int AFPReadFromRing(AFPThreadVars
*ptv
)
862 uint8_t emergency_flush
= 0;
867 /* Loop till we have packets available */
869 if (unlikely(suricata_ctl_flags
!= 0)) {
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
);
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
);
888 if (++ptv
->frame_offset
>= ptv
->req
.v2
.tp_frame_nr
) {
889 ptv
->frame_offset
= 0;
893 if ((emergency_flush
) && (ptv
->flags
& AFP_EMERGENCY_MODE
)) {
894 SCReturnInt(AFP_KERNEL_DROP
);
896 SCReturnInt(AFP_READ_OK
);
903 /* Our packet is still used by suricata, we exit read loop to
905 if (h
.h2
->tp_status
& TP_STATUS_USER_BUSY
) {
906 SCReturnInt(AFP_READ_OK
);
909 if ((ptv
->flags
& AFP_EMERGENCY_MODE
) && (emergency_flush
== 1)) {
910 h
.h2
->tp_status
= TP_STATUS_KERNEL
;
914 p
= PacketGetFromQueueOrAlloc();
916 SCReturnInt(AFP_SURI_FAILURE
);
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
;
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
;
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
939 h
.h2
->tp_status
|= TP_STATUS_USER_BUSY
;
942 p
->livedev
= ptv
->livedev
;
943 p
->datalink
= ptv
->datalink
;
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
);
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;
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
);
963 p
->afp_v
.relptr
= h
.raw
;
964 p
->ReleasePacket
= AFPReleasePacket
;
965 p
->afp_v
.mpeer
= ptv
->mpeer
;
966 AFPRefSocket(ptv
->mpeer
);
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
;
972 p
->afp_v
.peer
= NULL
;
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.
980 h
.h2
->tp_status
= TP_STATUS_KERNEL
;
981 if (++ptv
->frame_offset
>= ptv
->req
.v2
.tp_frame_nr
) {
982 ptv
->frame_offset
= 0;
984 TmqhOutputPacketpool(ptv
->tv
, p
);
985 SCReturnInt(AFP_SURI_FAILURE
);
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
));
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
;
1008 if (h
.h2
->tp_status
& TP_STATUS_CSUMNOTREADY
) {
1009 p
->flags
|= PKT_IGNORE_CHECKSUM
;
1012 if (h
.h2
->tp_status
& TP_STATUS_LOSING
) {
1013 emergency_flush
= 1;
1014 AFPDumpCounters(ptv
);
1017 /* release frame if not in zero copy mode */
1018 if (!(ptv
->flags
& AFP_ZERO_COPY
)) {
1019 h
.h2
->tp_status
= TP_STATUS_KERNEL
;
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;
1027 TmqhOutputPacketpool(ptv
->tv
, p
);
1028 SCReturnInt(AFP_SURI_FAILURE
);
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
);
1039 SCReturnInt(AFP_READ_OK
);
1042 #ifdef HAVE_TPACKET_V3
1043 static inline void AFPFlushBlock(struct tpacket_block_desc
*pbd
)
1045 pbd
->hdr
.bh1
.block_status
= TP_STATUS_KERNEL
;
1048 static inline int AFPParsePacketV3(AFPThreadVars
*ptv
, struct tpacket_block_desc
*pbd
, struct tpacket3_hdr
*ppd
)
1050 Packet
*p
= PacketGetFromQueueOrAlloc();
1052 SCReturnInt(AFP_SURI_FAILURE
);
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
;
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
;
1072 p
->livedev
= ptv
->livedev
;
1073 p
->datalink
= ptv
->datalink
;
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;
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
);
1087 p
->afp_v
.relptr
= ppd
;
1088 p
->ReleasePacket
= AFPReleasePacketV3
;
1089 p
->afp_v
.mpeer
= ptv
->mpeer
;
1090 AFPRefSocket(ptv
->mpeer
);
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
;
1096 p
->afp_v
.peer
= NULL
;
1099 if (PacketCopyData(p
, (unsigned char*)ppd
+ ppd
->tp_mac
, ppd
->tp_snaplen
) == -1) {
1100 TmqhOutputPacketpool(ptv
->tv
, p
);
1101 SCReturnInt(AFP_SURI_FAILURE
);
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
));
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
;
1123 if (ppd
->tp_status
& TP_STATUS_CSUMNOTREADY
) {
1124 p
->flags
|= PKT_IGNORE_CHECKSUM
;
1128 if (TmThreadsSlotProcessPkt(ptv
->tv
, ptv
->slot
, p
) != TM_ECODE_OK
) {
1129 TmqhOutputPacketpool(ptv
->tv
, p
);
1130 SCReturnInt(AFP_SURI_FAILURE
);
1133 SCReturnInt(AFP_READ_OK
);
1136 static inline int AFPWalkBlock(AFPThreadVars
*ptv
, struct tpacket_block_desc
*pbd
)
1138 int num_pkts
= pbd
->hdr
.bh1
.num_pkts
, i
;
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
);
1149 case AFP_SURI_FAILURE
:
1150 /* Internal error but let's just continue and
1151 * treat thenext packet */
1153 case AFP_READ_FAILURE
:
1154 SCReturnInt(AFP_READ_FAILURE
);
1158 ppd
= ppd
+ ((struct tpacket3_hdr
*)ppd
)->tp_next_offset
;
1161 SCReturnInt(AFP_READ_OK
);
1163 #endif /* HAVE_TPACKET_V3 */
1166 * \brief AF packet read function for ring
1168 * This function fills
1169 * From here the packets are picked up by the DecodeAFP thread.
1171 * \param user pointer to AFPThreadVars
1172 * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
1174 static int AFPReadFromRingV3(AFPThreadVars
*ptv
)
1176 #ifdef HAVE_TPACKET_V3
1177 struct tpacket_block_desc
*pbd
;
1180 /* Loop till we have packets available */
1182 if (unlikely(suricata_ctl_flags
!= 0)) {
1183 SCLogInfo("Exiting AFP V3 read loop");
1187 pbd
= (struct tpacket_block_desc
*) ptv
->ring
.v3
[ptv
->frame_offset
].iov_base
;
1189 /* block is not ready to be read */
1190 if ((pbd
->hdr
.bh1
.block_status
& TP_STATUS_USER
) == 0) {
1191 SCReturnInt(AFP_READ_OK
);
1194 ret
= AFPWalkBlock(ptv
, pbd
);
1195 if (unlikely(ret
!= AFP_READ_OK
)) {
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
);
1208 SCReturnInt(AFP_READ_OK
);
1212 * \brief Reference socket
1214 * \retval O in case of failure, 1 in case of success
1216 static int AFPRefSocket(AFPPeer
* peer
)
1218 if (unlikely(peer
== NULL
))
1221 (void)SC_ATOMIC_ADD(peer
->sock_usage
, 1);
1227 * \brief Dereference socket
1229 * \retval 1 if socket is still alive, 0 if not
1231 static int AFPDerefSocket(AFPPeer
* peer
)
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
));
1246 static void AFPSwitchState(AFPThreadVars
*ptv
, int state
)
1248 ptv
->afp_state
= state
;
1249 ptv
->down_count
= 0;
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
;
1264 /* only used in reading phase, we can free it */
1265 SCFree(ptv
->ring
.v2
);
1266 ptv
->ring
.v2
= NULL
;
1268 #ifdef HAVE_TPACKET_V3
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
);
1281 if (state
== AFP_STATE_UP
) {
1282 (void)SC_ATOMIC_SET(ptv
->mpeer
->sock_usage
, 1);
1286 static int AFPReadAndDiscard(AFPThreadVars
*ptv
, struct timeval
*synctv
,
1287 uint64_t *discarded_pkts
)
1289 struct sockaddr_ll from
;
1294 struct cmsghdr cmsg
;
1295 char buf
[CMSG_SPACE(sizeof(struct tpacket_auxdata
))];
1299 if (unlikely(suricata_ctl_flags
!= 0)) {
1303 msg
.msg_name
= &from
;
1304 msg
.msg_namelen
= sizeof(from
);
1307 msg
.msg_control
= &cmsg_buf
;
1308 msg
.msg_controllen
= sizeof(cmsg_buf
);
1311 iov
.iov_len
= ptv
->datalen
;
1312 iov
.iov_base
= ptv
->data
;
1314 (void)recvmsg(ptv
->socket
, &msg
, MSG_TRUNC
);
1316 if (ioctl(ptv
->socket
, SIOCGSTAMP
, &ts
) == -1) {
1321 if ((ts
.tv_sec
> synctv
->tv_sec
) ||
1322 (ts
.tv_sec
>= synctv
->tv_sec
&&
1323 ts
.tv_usec
> synctv
->tv_usec
)) {
1329 static int AFPReadAndDiscardFromRing(AFPThreadVars
*ptv
, struct timeval
*synctv
,
1330 uint64_t *discarded_pkts
)
1334 if (unlikely(suricata_ctl_flags
!= 0)) {
1338 #ifdef HAVE_TPACKET_V3
1339 if (ptv
->flags
& AFP_TPACKET_V3
) {
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
)) {
1352 ptv
->frame_offset
= (ptv
->frame_offset
+ 1) % ptv
->req
.v3
.tp_block_nr
;
1358 /* Read packet from ring */
1359 h
.raw
= (((union thdr
**)ptv
->ring
.v2
)[ptv
->frame_offset
]);
1360 if (h
.raw
== NULL
) {
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
)) {
1370 h
.h2
->tp_status
= TP_STATUS_KERNEL
;
1371 if (++ptv
->frame_offset
>= ptv
->req
.v2
.tp_frame_nr
) {
1372 ptv
->frame_offset
= 0;
1380 /** \brief wait for all afpacket threads to fully init
1382 * Discard packets before all threads are ready, as the cluster
1383 * setup is not complete yet.
1385 * if AFPPeersListStarted() returns true init is complete
1387 * \retval r 1 = happy, otherwise unhappy
1389 static int AFPSynchronizeStart(AFPThreadVars
*ptv
, uint64_t *discarded_pkts
)
1391 struct timeval synctv
;
1394 fds
.fd
= ptv
->socket
;
1395 fds
.events
= POLLIN
;
1397 /* Set timeval to end of the world */
1398 synctv
.tv_sec
= 0xffffffff;
1399 synctv
.tv_usec
= 0xffffffff;
1402 int r
= poll(&fds
, 1, POLL_TIMEOUT
);
1404 (fds
.revents
& (POLLHUP
|POLLRDHUP
|POLLERR
|POLLNVAL
))) {
1405 SCLogWarning(SC_ERR_AFP_READ
, "poll failed %02x",
1406 fds
.revents
& (POLLHUP
|POLLRDHUP
|POLLERR
|POLLNVAL
));
1409 if (AFPPeersListStarted() && synctv
.tv_sec
== (time_t) 0xffffffff) {
1410 gettimeofday(&synctv
, NULL
);
1412 if (ptv
->flags
& AFP_RING_MODE
) {
1413 r
= AFPReadAndDiscardFromRing(ptv
, &synctv
, discarded_pkts
);
1415 r
= AFPReadAndDiscard(ptv
, &synctv
, discarded_pkts
);
1417 SCLogDebug("Discarding on %s", ptv
->tv
->name
);
1420 SCLogDebug("Starting to read on %s", ptv
->tv
->name
);
1426 } else if (r
== 0 && AFPPeersListStarted()) {
1427 SCLogDebug("Starting to read on %s", ptv
->tv
->name
);
1429 } else if (r
< 0) { /* only exit on error */
1430 SCLogWarning(SC_ERR_AFP_READ
, "poll failed with retval %d", r
);
1438 * \brief Try to reopen socket
1440 * \retval 0 in case of success, negative if error occurs or a condition
1443 static int AFPTryReopen(AFPThreadVars
*ptv
)
1447 /* Don't reconnect till we have packet that did not release data */
1448 if (SC_ATOMIC_GET(ptv
->mpeer
->sock_usage
) != 0) {
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'",
1458 return afp_activate_r
;
1461 SCLogInfo("Interface '%s' is back", ptv
->iface
);
1466 * \brief Main AF_PACKET reading Loop function
1468 TmEcode
ReceiveAFPLoop(ThreadVars
*tv
, void *data
, void *slot
)
1472 AFPThreadVars
*ptv
= (AFPThreadVars
*)data
;
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;
1481 ptv
->slot
= s
->slot_next
;
1483 if (ptv
->flags
& AFP_RING_MODE
) {
1484 if (ptv
->flags
& AFP_TPACKET_V3
) {
1485 AFPReadFunc
= AFPReadFromRingV3
;
1487 AFPReadFunc
= AFPReadFromRing
;
1490 AFPReadFunc
= AFPRead
;
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
)) {
1497 if (suricata_ctl_flags
!= 0) {
1501 r
= AFPCreateSocket(ptv
, ptv
->iface
, 1);
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");
1511 AFPPeersListReachedInc();
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) {
1524 SCLogDebug("(%s) Kernel socket startup: Packets %" PRIu32
1525 ", dropped %" PRIu32
"",
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
);
1535 fds
.fd
= ptv
->socket
;
1536 fds
.events
= POLLIN
;
1539 /* Start by checking the state of our interface */
1540 if (unlikely(ptv
->afp_state
== AFP_STATE_DOWN
)) {
1544 usleep(AFP_RECONNECT_TIMEOUT
);
1545 if (suricata_ctl_flags
!= 0) {
1549 r
= AFPTryReopen(ptv
);
1550 fds
.fd
= ptv
->socket
;
1556 /* make sure we have at least one packet in the packet pool, to prevent
1557 * us from alloc'ing packets at line rate */
1560 r
= poll(&fds
, 1, POLL_TIMEOUT
);
1562 if (suricata_ctl_flags
!= 0) {
1567 (fds
.revents
& (POLLHUP
|POLLRDHUP
|POLLERR
|POLLNVAL
))) {
1568 if (fds
.revents
& (POLLHUP
| POLLRDHUP
)) {
1569 AFPSwitchState(ptv
, AFP_STATE_DOWN
);
1571 } else if (fds
.revents
& POLLERR
) {
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
);
1581 } else if (fds
.revents
& POLLNVAL
) {
1582 SCLogError(SC_ERR_AFP_READ
, "Invalid polling request");
1583 AFPSwitchState(ptv
, AFP_STATE_DOWN
);
1587 r
= AFPReadFunc(ptv
);
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
;
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
);
1604 case AFP_SURI_FAILURE
:
1605 StatsIncr(ptv
->tv
, ptv
->capture_errors
);
1607 case AFP_KERNEL_DROP
:
1608 AFPDumpCounters(ptv
);
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
;
1618 /* poll timed out, lets see handle our timeout path */
1619 TmThreadsCaptureHandleTimeout(tv
, ptv
->slot
, NULL
);
1621 } else if ((r
< 0) && (errno
!= EINTR
)) {
1622 SCLogError(SC_ERR_AFP_READ
, "Error reading data from iface '%s': (%d) %s",
1624 errno
, strerror(errno
));
1625 AFPSwitchState(ptv
, AFP_STATE_DOWN
);
1628 StatsSyncCountersIfSignalled(tv
);
1631 AFPDumpCounters(ptv
);
1632 StatsSyncCountersIfSignalled(tv
);
1633 SCReturnInt(TM_ECODE_OK
);
1636 static int AFPGetDevFlags(int fd
, const char *ifname
)
1640 memset(&ifr
, 0, sizeof(ifr
));
1641 strlcpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
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
));
1649 return ifr
.ifr_flags
;
1653 static int AFPGetIfnumByDev(int fd
, const char *ifname
, int verbose
)
1657 memset(&ifr
, 0, sizeof(ifr
));
1658 strlcpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
1660 if (ioctl(fd
, SIOCGIFINDEX
, &ifr
) == -1) {
1662 SCLogError(SC_ERR_AFP_CREATE
, "Unable to find iface %s: %s",
1663 ifname
, strerror(errno
));
1667 return ifr
.ifr_ifindex
;
1670 static int AFPGetDevLinktype(int fd
, const char *ifname
)
1674 memset(&ifr
, 0, sizeof(ifr
));
1675 strlcpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
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
));
1683 switch (ifr
.ifr_hwaddr
.sa_family
) {
1684 case ARPHRD_LOOPBACK
:
1685 return LINKTYPE_ETHERNET
;
1688 return LINKTYPE_RAW
;
1690 return ifr
.ifr_hwaddr
.sa_family
;
1694 int AFPGetLinkType(const char *ifname
)
1698 int fd
= socket(AF_PACKET
, SOCK_RAW
, htons(ETH_P_ALL
));
1700 SCLogError(SC_ERR_AFP_CREATE
, "Couldn't create a AF_PACKET socket, error %s", strerror(errno
));
1701 return LINKTYPE_RAW
;
1704 ltype
= AFPGetDevLinktype(fd
, ifname
);
1710 static int AFPComputeRingParams(AFPThreadVars
*ptv
, int order
)
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
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)
1726 described in packet_mmap.txt
1727 dependant on snaplen (need to use a variable ?)
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);
1735 int tp_hdrlen
= sizeof(struct tpacket_hdr
);
1736 int snaplen
= default_packet_size
;
1739 snaplen
= GetIfaceMaxPacketSize(ptv
->iface
);
1741 SCLogWarning(SC_ERR_INVALID_VALUE
,
1742 "Unable to get MTU, setting snaplen to sane default of 1514");
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");
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
);
1764 #ifdef HAVE_TPACKET_V3
1765 static int AFPComputeRingParamsV3(AFPThreadVars
*ptv
)
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
;
1774 snaplen
= GetIfaceMaxPacketSize(ptv
->iface
);
1776 SCLogWarning(SC_ERR_INVALID_VALUE
,
1777 "Unable to get MTU, setting snaplen to sane default of 1514");
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
;
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
);
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
1805 static int AFPSetupRing(AFPThreadVars
*ptv
, char *devname
)
1808 unsigned int len
= sizeof(val
), i
;
1812 #ifdef HAVE_TPACKET_V3
1813 if (ptv
->flags
& AFP_TPACKET_V3
) {
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)");
1826 SCLogError(SC_ERR_AFP_CREATE
,
1827 "Too old kernel giving up (need 2.6.27 at least)");
1830 SCLogError(SC_ERR_AFP_CREATE
, "Error when retrieving packet header len");
1831 return AFP_FATAL_ERROR
;
1835 #ifdef HAVE_TPACKET_V3
1836 if (ptv
->flags
& AFP_TPACKET_V3
) {
1840 if (setsockopt(ptv
->socket
, SOL_PACKET
, PACKET_VERSION
, &val
,
1842 SCLogError(SC_ERR_AFP_CREATE
,
1843 "Can't activate TPACKET_V2/TPACKET_V3 on packet socket: %s",
1845 return AFP_FATAL_ERROR
;
1848 #ifdef HAVE_HW_TIMESTAMPING
1849 int req
= SOF_TIMESTAMPING_RAW_HARDWARE
;
1850 if (setsockopt(ptv
->socket
, SOL_PACKET
, PACKET_TIMESTAMP
, (void *) &req
,
1852 SCLogWarning(SC_ERR_AFP_CREATE
,
1853 "Can't activate hardware timestamping on packet socket: %s",
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",
1869 return AFP_FATAL_ERROR
;
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
;
1879 r
= setsockopt(ptv
->socket
, SOL_PACKET
, PACKET_RX_RING
,
1880 (void *) &ptv
->req
.v3
, sizeof(ptv
->req
.v3
));
1882 SCLogError(SC_ERR_MEM_ALLOC
,
1883 "Unable to allocate RX Ring for iface %s: (%d) %s",
1887 return AFP_FATAL_ERROR
;
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
;
1897 r
= setsockopt(ptv
->socket
, SOL_PACKET
, PACKET_RX_RING
,
1898 (void *) &ptv
->req
, sizeof(ptv
->req
));
1901 if (errno
== ENOMEM
) {
1902 SCLogInfo("Memory issue with ring parameters. Retrying.");
1905 SCLogError(SC_ERR_MEM_ALLOC
,
1906 "Unable to allocate RX Ring for iface %s: (%d) %s",
1910 return AFP_FATAL_ERROR
;
1916 SCLogError(SC_ERR_MEM_ALLOC
,
1917 "Unable to allocate RX Ring for iface %s (order 0 failed)",
1919 return AFP_FATAL_ERROR
;
1921 #ifdef HAVE_TPACKET_V3
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
;
1931 ptv
->ring_buflen
= ptv
->req
.v2
.tp_block_nr
* ptv
->req
.v2
.tp_block_size
;
1932 #ifdef HAVE_TPACKET_V3
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",
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");
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
;
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");
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
]);
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
;
1975 ptv
->frame_offset
= 0;
1976 #ifdef HAVE_TPACKET_V3
1983 munmap(ptv
->ring_buf
, ptv
->ring_buflen
);
1985 SCFree(ptv
->ring
.v2
);
1987 SCFree(ptv
->ring
.v3
);
1989 /* Packet mmap does the cleaning when socket is closed */
1990 return AFP_FATAL_ERROR
;
1993 /** \brief test if we can use FANOUT. Older kernels like those in
1994 * CentOS6 have HAVE_PACKET_FANOUT defined but fail to work
1996 int AFPIsFanoutSupported(void)
1998 #ifdef HAVE_PACKET_FANOUT
1999 int fd
= socket(AF_PACKET
, SOCK_RAW
, htons(ETH_P_ALL
));
2003 uint16_t mode
= PACKET_FANOUT_HASH
| PACKET_FANOUT_FLAG_DEFRAG
;
2005 uint32_t option
= (mode
<< 16) | (id
& 0xffff);
2006 int r
= setsockopt(fd
, SOL_PACKET
, PACKET_FANOUT
,(void *)&option
, sizeof(option
));
2010 SCLogPerf("fanout not supported by kernel: %s", strerror(errno
));
2019 #ifdef HAVE_PACKET_EBPF
2021 static int SockFanoutSeteBPF(AFPThreadVars
*ptv
)
2023 int pfd
= ptv
->ebpf_lb_fd
;
2025 SCLogError(SC_ERR_INVALID_VALUE
,
2026 "Fanout file descriptor is invalid");
2030 if (setsockopt(ptv
->socket
, SOL_PACKET
, PACKET_FANOUT_DATA
, &pfd
, sizeof(pfd
))) {
2031 SCLogError(SC_ERR_INVALID_VALUE
, "Error setting ebpf");
2034 SCLogInfo("Activated eBPF on socket");
2039 static int SetEbpfFilter(AFPThreadVars
*ptv
)
2041 int pfd
= ptv
->ebpf_filter_fd
;
2043 SCLogError(SC_ERR_INVALID_VALUE
,
2044 "Filter file descriptor is invalid");
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
));
2052 SCLogInfo("Activated eBPF filter on socket");
2058 static int AFPCreateSocket(AFPThreadVars
*ptv
, char *devname
, int verbose
)
2061 int ret
= AFP_FATAL_ERROR
;
2062 struct packet_mreq sock_params
;
2063 struct sockaddr_ll bind_address
;
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
));
2073 if_idx
= AFPGetIfnumByDev(ptv
->socket
, devname
, verbose
);
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) {
2086 SCLogError(SC_ERR_AFP_CREATE
, "Couldn't find iface %s", devname
);
2087 ret
= AFP_RECOVERABLE_ERROR
;
2091 int if_flags
= AFPGetDevFlags(ptv
->socket
, ptv
->iface
);
2092 if (if_flags
== -1) {
2094 SCLogError(SC_ERR_AFP_READ
,
2095 "Couldn't get flags for interface '%s'",
2098 ret
= AFP_RECOVERABLE_ERROR
;
2100 } else if ((if_flags
& (IFF_UP
| IFF_RUNNING
)) == 0) {
2102 SCLogError(SC_ERR_AFP_READ
,
2103 "Interface '%s' is down",
2106 ret
= AFP_RECOVERABLE_ERROR
;
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
));
2117 SCLogError(SC_ERR_AFP_CREATE
,
2118 "Couldn't switch iface %s to promiscuous, error %s",
2119 devname
, strerror(errno
));
2124 if (ptv
->checksum_mode
== CHECKSUM_VALIDATION_KERNEL
) {
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
;
2134 /* set socket recv buffer size */
2135 if (ptv
->buffer_size
!= 0) {
2137 * Set the socket buffer size to the specified value.
2139 SCLogPerf("Setting AF_PACKET socket buffer to %d", ptv
->buffer_size
);
2140 if (setsockopt(ptv
->socket
, SOL_SOCKET
, SO_RCVBUF
,
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
));
2150 r
= bind(ptv
->socket
, (struct sockaddr
*)&bind_address
, sizeof(bind_address
));
2153 if (errno
== ENETDOWN
) {
2154 SCLogError(SC_ERR_AFP_CREATE
,
2155 "Couldn't bind AF_PACKET socket, iface %s is down",
2158 SCLogError(SC_ERR_AFP_CREATE
,
2159 "Couldn't bind AF_PACKET socket to iface %s, error %s",
2160 devname
, strerror(errno
));
2163 ret
= AFP_RECOVERABLE_ERROR
;
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
));
2176 SCLogError(SC_ERR_AFP_CREATE
,
2177 "Couldn't set fanout mode, error %s",
2184 #ifdef HAVE_PACKET_EBPF
2185 if (ptv
->cluster_type
== PACKET_FANOUT_EBPF
) {
2186 r
= SockFanoutSeteBPF(ptv
);
2188 SCLogError(SC_ERR_AFP_CREATE
,
2189 "Coudn't set EBPF, error %s",
2196 if (ptv
->flags
& AFP_RING_MODE
) {
2197 ret
= AFPSetupRing(ptv
, devname
);
2202 SCLogDebug("Using interface '%s' via socket %d", (char *)devname
, ptv
->socket
);
2204 ptv
->datalink
= AFPGetDevLinktype(ptv
->socket
, ptv
->iface
);
2205 switch (ptv
->datalink
) {
2212 TmEcode rc
= AFPSetBPFFilter(ptv
);
2213 if (rc
== TM_ECODE_FAILED
) {
2214 ret
= AFP_FATAL_ERROR
;
2219 AFPSwitchState(ptv
, AFP_STATE_UP
);
2225 if (ptv
->flags
& AFP_TPACKET_V3
) {
2227 SCFree(ptv
->ring
.v3
);
2228 ptv
->ring
.v3
= NULL
;
2232 SCFree(ptv
->ring
.v2
);
2233 ptv
->ring
.v2
= NULL
;
2241 TmEcode
AFPSetBPFFilter(AFPThreadVars
*ptv
)
2243 struct bpf_program filter
;
2244 struct sock_fprog fcode
;
2247 #ifdef HAVE_PACKET_EBPF
2248 if (ptv
->ebpf_filter_fd
!= -1) {
2249 return SetEbpfFilter(ptv
);
2253 if (!ptv
->bpf_filter
)
2256 SCLogInfo("Using BPF '%s' on iface '%s'",
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 */
2268 sizeof(errbuf
)) == -1) {
2269 SCLogError(SC_ERR_AFP_CREATE
, "Failed to compile BPF \"%s\": %s",
2272 return TM_ECODE_FAILED
;
2275 fcode
.len
= filter
.bf_len
;
2276 fcode
.filter
= (struct sock_filter
*)filter
.bf_insns
;
2278 rc
= setsockopt(ptv
->socket
, SOL_SOCKET
, SO_ATTACH_FILTER
, &fcode
, sizeof(fcode
));
2282 SCLogError(SC_ERR_AFP_CREATE
, "Failed to attach filter: %s", strerror(errno
));
2283 return TM_ECODE_FAILED
;
2289 #ifdef HAVE_PACKET_EBPF
2291 * Insert a half flow in the kernel bypass table
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
2297 static int AFPInsertHalfFlow(int mapd
, void *key
, unsigned int nr_cpus
)
2299 BPF_DECLARE_PERCPU(struct pair
, value
, nr_cpus
);
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;
2312 if (bpf_map_update_elem(mapd
, key
, value
, BPF_NOEXIST
) != 0) {
2314 /* no more place in the hash */
2317 /* no more place in the hash for some hardware bypass */
2320 /* if we already have the key then bypass is a success */
2323 /* Not supposed to be there so issue a error */
2325 SCLogError(SC_ERR_BPF
, "Can't update eBPF map: %s (%d)",
2334 static int AFPSetFlowStorage(Packet
*p
, int map_fd
, void *key0
, void* key1
,
2337 FlowBypassInfo
*fc
= FlowGetStorageById(p
->flow
, GetFlowBypassInfoID());
2339 EBPFBypassData
*eb
= SCCalloc(1, sizeof(EBPFBypassData
));
2341 EBPFDeleteKey(map_fd
, key0
);
2342 EBPFDeleteKey(map_fd
, key1
);
2343 LiveDevAddBypassFail(p
->livedev
, 1, family
);
2351 eb
->cpus_count
= p
->afp_v
.nr_cpus
;
2352 fc
->BypassUpdate
= EBPFBypassUpdate
;
2353 fc
->BypassFree
= EBPFBypassFree
;
2354 fc
->bypass_data
= eb
;
2356 EBPFDeleteKey(map_fd
, key0
);
2357 EBPFDeleteKey(map_fd
, key1
);
2358 LiveDevAddBypassFail(p
->livedev
, 1, family
);
2364 LiveDevAddBypassStats(p
->livedev
, 1, family
);
2371 * Bypass function for AF_PACKET capture in eBPF mode
2373 * This function creates two half flows in the map shared with the kernel
2374 * to trigger bypass.
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
2381 * \param p the packet belonging to the flow to bypass
2382 * \return 0 if unable to bypass, 1 if success
2384 static int AFPBypassCallback(Packet
*p
)
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
))) {
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
) {
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
)) {
2405 if (PKT_IS_IPV4(p
)) {
2406 SCLogDebug("add an IPv4");
2407 if (p
->afp_v
.v4_map_fd
== -1) {
2410 struct flowv4_keys
*keys
[2];
2411 keys
[0] = SCCalloc(1, sizeof(struct flowv4_keys
));
2412 if (keys
[0] == NULL
) {
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];
2422 if (IPV4_GET_IPPROTO(p
) == IPPROTO_TCP
) {
2423 keys
[0]->ip_proto
= 1;
2425 keys
[0]->ip_proto
= 0;
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
);
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
);
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];
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
);
2456 EBPFUpdateFlow(p
->flow
, p
, NULL
);
2457 return AFPSetFlowStorage(p
, p
->afp_v
.v4_map_fd
, keys
[0], keys
[1], AF_INET
);
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
))) {
2463 if (p
->afp_v
.v6_map_fd
== -1) {
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
);
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
]);
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];
2482 if (IPV6_GET_NH(p
) == IPPROTO_TCP
) {
2483 keys
[0]->ip_proto
= 1;
2485 keys
[0]->ip_proto
= 0;
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
);
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
);
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
]);
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];
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
);
2519 EBPFUpdateFlow(p
->flow
, p
, NULL
);
2520 return AFPSetFlowStorage(p
, p
->afp_v
.v6_map_fd
, keys
[0], keys
[1], AF_INET6
);
2527 * Bypass function for AF_PACKET capture in XDP mode
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
2534 * \param p the packet belonging to the flow to bypass
2535 * \return 0 if unable to bypass, 1 if success
2537 static int AFPXDPBypassCallback(Packet
*p
)
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
))) {
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
) {
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
)) {
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
);
2565 if (p
->afp_v
.v4_map_fd
== -1) {
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;
2580 keys
[0]->ip_proto
= 0;
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
);
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
);
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
);
2610 return AFPSetFlowStorage(p
, p
->afp_v
.v4_map_fd
, keys
[0], keys
[1], AF_INET
);
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) {
2620 struct flowv6_keys
*keys
[2];
2621 keys
[0] = SCCalloc(1, sizeof(struct flowv6_keys
));
2622 if (keys
[0] == NULL
) {
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
];
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;
2637 keys
[0]->ip_proto
= 0;
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
);
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
);
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
];
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
);
2669 return AFPSetFlowStorage(p
, p
->afp_v
.v6_map_fd
, keys
[0], keys
[1], AF_INET6
);
2676 bool g_flowv4_ok
= true;
2677 bool g_flowv6_ok
= true;
2680 * \brief Init function for ReceiveAFP.
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
2686 * \todo Create a general AFP setup function.
2688 TmEcode
ReceiveAFPThreadInit(ThreadVars
*tv
, const void *initdata
, void **data
)
2691 AFPIfaceConfig
*afpconfig
= (AFPIfaceConfig
*)initdata
;
2693 if (initdata
== NULL
) {
2694 SCLogError(SC_ERR_INVALID_ARGUMENT
, "initdata == NULL");
2695 SCReturnInt(TM_ECODE_FAILED
);
2698 AFPThreadVars
*ptv
= SCMalloc(sizeof(AFPThreadVars
));
2699 if (unlikely(ptv
== NULL
)) {
2700 afpconfig
->DerefFunc(afpconfig
);
2701 SCReturnInt(TM_ECODE_FAILED
);
2703 memset(ptv
, 0, sizeof(AFPThreadVars
));
2708 strlcpy(ptv
->iface
, afpconfig
->iface
, AFP_IFACE_NAME_LENGTH
);
2709 ptv
->iface
[AFP_IFACE_NAME_LENGTH
- 1]= '\0';
2711 ptv
->livedev
= LiveGetDevice(ptv
->iface
);
2712 if (ptv
->livedev
== NULL
) {
2713 SCLogError(SC_ERR_INVALID_VALUE
, "Unable to find Live device");
2715 SCReturnInt(TM_ECODE_FAILED
);
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
;
2723 ptv
->promisc
= afpconfig
->promisc
;
2724 ptv
->checksum_mode
= afpconfig
->checksum_mode
;
2725 ptv
->bpf_filter
= NULL
;
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
;
2738 ptv
->flags
= afpconfig
->flags
;
2740 if (afpconfig
->bpf_filter
) {
2741 ptv
->bpf_filter
= afpconfig
->bpf_filter
;
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();
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'",
2758 ptv
->v6_map_fd
= EBPFGetMapFDByName(ptv
->iface
, "flow_table_v6");
2759 if (ptv
->v6_map_fd
== -1) {
2761 SCLogError(SC_ERR_INVALID_VALUE
, "Can't find eBPF map fd for '%s'",
2763 g_flowv6_ok
= false;
2767 ptv
->ebpf_t_config
= afpconfig
->ebpf_t_config
;
2770 #ifdef PACKET_STATISTICS
2771 ptv
->capture_kernel_packets
= StatsRegisterCounter("capture.kernel_packets",
2773 ptv
->capture_kernel_drops
= StatsRegisterCounter("capture.kernel_drops",
2775 ptv
->capture_errors
= StatsRegisterCounter("capture.errors",
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.");
2791 if (AFPPeersListAdd(ptv
) == TM_ECODE_FAILED
) {
2793 afpconfig
->DerefFunc(afpconfig
);
2794 SCReturnInt(TM_ECODE_FAILED
);
2797 #define T_DATA_SIZE 70000
2798 ptv
->data
= SCMalloc(T_DATA_SIZE
);
2799 if (ptv
->data
== NULL
) {
2800 afpconfig
->DerefFunc(afpconfig
);
2802 SCReturnInt(TM_ECODE_FAILED
);
2804 ptv
->datalen
= T_DATA_SIZE
;
2807 *data
= (void *)ptv
;
2809 afpconfig
->DerefFunc(afpconfig
);
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 */
2815 if ((ConfGetBool("vlan.use-for-tracking", &vlanbool
)) == 1 && vlanbool
== 0) {
2816 ptv
->flags
|= AFP_VLAN_DISABLED
;
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
;
2826 SCReturnInt(TM_ECODE_OK
);
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
2834 void ReceiveAFPThreadExitStats(ThreadVars
*tv
, void *data
)
2837 AFPThreadVars
*ptv
= (AFPThreadVars
*)data
;
2839 #ifdef PACKET_STATISTICS
2840 AFPDumpCounters(ptv
);
2841 SCLogPerf("(%s) Kernel: Packets %" PRIu64
", dropped %" PRIu64
"",
2843 StatsGetLocalCounterValue(tv
, ptv
->capture_kernel_packets
),
2844 StatsGetLocalCounterValue(tv
, ptv
->capture_kernel_drops
));
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
2853 TmEcode
ReceiveAFPThreadDeinit(ThreadVars
*tv
, void *data
)
2855 AFPThreadVars
*ptv
= (AFPThreadVars
*)data
;
2857 AFPSwitchState(ptv
, AFP_STATE_DOWN
);
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
);
2865 if (ptv
->data
!= NULL
) {
2871 ptv
->bpf_filter
= NULL
;
2872 if ((ptv
->flags
& AFP_TPACKET_V3
) && ptv
->ring
.v3
) {
2873 SCFree(ptv
->ring
.v3
);
2876 SCFree(ptv
->ring
.v2
);
2880 SCReturnInt(TM_ECODE_OK
);
2884 * \brief This function passes off to link type decoders.
2886 * DecodeAFP reads packets from the PacketQueue and passes
2887 * them off to the proper link type decoder.
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
2894 TmEcode
DecodeAFP(ThreadVars
*tv
, Packet
*p
, void *data
, PacketQueue
*pq
, PacketQueue
*postpq
)
2897 DecodeThreadVars
*dtv
= (DecodeThreadVars
*)data
;
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
)
2904 /* update counters */
2905 DecodeUpdatePacketCounters(tv
, dtv
, p
);
2907 /* If suri has set vlan during reading, we increase vlan counter */
2909 StatsIncr(tv
, dtv
->counter_vlan
);
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
);
2917 case LINKTYPE_LINUX_SLL
:
2918 DecodeSll(tv
, dtv
, p
, GET_PKT_DATA(p
), GET_PKT_LEN(p
), pq
);
2921 DecodePPP(tv
, dtv
, p
, GET_PKT_DATA(p
), GET_PKT_LEN(p
), pq
);
2924 case LINKTYPE_GRE_OVER_IP
:
2925 DecodeRaw(tv
, dtv
, p
, GET_PKT_DATA(p
), GET_PKT_LEN(p
), pq
);
2928 DecodeNull(tv
, dtv
, p
, GET_PKT_DATA(p
), GET_PKT_LEN(p
), pq
);
2931 SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED
, "Error: datalink type %" PRId32
" not yet supported in module DecodeAFP", p
->datalink
);
2935 PacketDecodeFinalize(tv
, dtv
, p
);
2937 SCReturnInt(TM_ECODE_OK
);
2940 TmEcode
DecodeAFPThreadInit(ThreadVars
*tv
, const void *initdata
, void **data
)
2943 DecodeThreadVars
*dtv
= NULL
;
2945 dtv
= DecodeThreadVarsAlloc(tv
);
2948 SCReturnInt(TM_ECODE_FAILED
);
2950 DecodeRegisterPerfCounters(dtv
, tv
);
2952 *data
= (void *)dtv
;
2954 SCReturnInt(TM_ECODE_OK
);
2957 TmEcode
DecodeAFPThreadDeinit(ThreadVars
*tv
, void *data
)
2960 DecodeThreadVarsFree(tv
, data
);
2961 SCReturnInt(TM_ECODE_OK
);
2964 #endif /* HAVE_AF_PACKET */