33 #define SC_PCAP_DONT_INCLUDE_PCAP_H 1
65 #include <sys/ioctl.h>
68 #if HAVE_LINUX_SOCKIOS_H
69 #include <linux/sockios.h>
72 #ifdef HAVE_PACKET_EBPF
73 #define PCAP_DONT_INCLUDE_PCAP_BPF_H 1
74 #include <bpf/libbpf.h>
79 struct bpf_insn *bf_insns;
87 #ifdef HAVE_PCAP_PCAP_H
88 #include <pcap/pcap.h>
93 #if HAVE_LINUX_IF_ETHER_H
94 #include <linux/if_ether.h>
97 #if HAVE_LINUX_IF_PACKET_H
98 #include <linux/if_packet.h>
101 #if HAVE_LINUX_IF_ARP_H
102 #include <linux/if_arp.h>
105 #if HAVE_LINUX_FILTER_H
106 #include <linux/filter.h>
110 #include <sys/mman.h>
113 #ifdef HAVE_HW_TIMESTAMPING
114 #include <linux/net_tstamp.h>
121 #ifndef HAVE_AF_PACKET
155 SCLogError(
"Error creating thread %s: you do not have "
156 "support for AF_PACKET enabled, on Linux host please recompile "
157 "with --enable-af-packet",
164 #define AFP_IFACE_NAME_LENGTH 48
166 #define AFP_STATE_DOWN 0
167 #define AFP_STATE_UP 1
169 #define AFP_RECONNECT_TIMEOUT 500000
170 #define AFP_DOWN_COUNTER_INTERVAL 40
172 #define POLL_TIMEOUT 100
175 #ifndef TP_STATUS_KERNEL
176 #define TP_STATUS_KERNEL 0
178 #ifndef TP_STATUS_USER
179 #define TP_STATUS_USER BIT_U32(0)
181 #ifndef TP_STATUS_COPY
182 #define TP_STATUS_COPY BIT_U32(1)
184 #ifndef TP_STATUS_LOSING
185 #define TP_STATUS_LOSING BIT_U32(2)
187 #ifndef TP_STATUS_CSUMNOTREADY
188 #define TP_STATUS_CSUMNOTREADY BIT_U32(3)
190 #ifndef TP_STATUS_VLAN_VALID
191 #define TP_STATUS_VLAN_VALID BIT_U32(4)
193 #ifndef TP_STATUS_BLK_TMO
194 #define TP_STATUS_BLK_TMO BIT_U32(5)
196 #ifndef TP_STATUS_VLAN_TPID_VALID
197 #define TP_STATUS_VLAN_TPID_VALID BIT_U32(6)
199 #ifndef TP_STATUS_CSUM_VALID
200 #define TP_STATUS_CSUM_VALID BIT_U32(7)
203 #ifndef TP_STATUS_TS_SOFTWARE
204 #define TP_STATUS_TS_SOFTWARE BIT_U32(29)
206 #ifndef TP_STATUS_TS_SYS_HARDWARE
207 #define TP_STATUS_TS_SYS_HARDWARE BIT_U32(30)
209 #ifndef TP_STATUS_TS_RAW_HARDWARE
210 #define TP_STATUS_TS_RAW_HARDWARE BIT_U32(31)
213 #ifndef TP_STATUS_USER_BUSY
225 #define TP_STATUS_USER_BUSY \
226 (uint32_t)((uint32_t)TP_STATUS_TS_SOFTWARE | (uint32_t)TP_STATUS_TS_SYS_HARDWARE | \
227 (uint32_t)TP_STATUS_TS_RAW_HARDWARE)
229 #define FRAME_BUSY(tp_status) \
230 (((uint32_t)(tp_status) & (uint32_t)TP_STATUS_USER_BUSY) == (uint32_t)TP_STATUS_USER_BUSY)
246 struct tpacket2_hdr *
h2;
247 struct tpacket3_hdr *
h3;
251 #ifdef HAVE_PACKET_EBPF
252 static int AFPBypassCallback(
Packet *
p);
253 static int AFPXDPBypassCallback(
Packet *
p);
275 #ifdef HAVE_PACKET_EBPF
337 struct tpacket_req
v2;
338 struct tpacket_req3
v3;
350 #ifdef HAVE_PACKET_EBPF
354 struct ebpf_timeout_config ebpf_t_config;
360 static void ReceiveAFPThreadExitStats(
ThreadVars *,
void *);
369 static int AFPGetIfnumByDev(
int fd,
const char *ifname,
int verbose);
370 static int AFPGetDevFlags(
int fd,
const char *ifname);
371 static int AFPDerefSocket(
AFPPeer* peer);
372 static int AFPRefSocket(
AFPPeer* peer);
423 if (ptv->
mpeer == NULL) {
434 static void AFPPeerClean(
AFPPeer *peer)
466 #define AFP_PEERS_MAX_TRY 4
467 #define AFP_PEERS_WAIT 20000
532 if (out_iface == NULL)
534 if (iface->
mtu != out_iface->
mtu) {
535 SCLogWarning(
"MTU on %s (%d) and %s (%d) are not equal, transmission of packets "
536 "bigger than %d will fail.",
550 static int AFPPeersListWaitTurn(
AFPPeer *peer)
561 static void AFPPeersListReachedInc(
void)
575 static int AFPPeersListStarted(
void)
612 static int AFPCreateSocket(
AFPThreadVars *ptv,
char *devname,
int verbose);
616 #ifdef PACKET_STATISTICS
617 struct tpacket_stats kstats;
618 socklen_t
len =
sizeof (
struct tpacket_stats);
619 if (getsockopt(ptv->
socket, SOL_PACKET, PACKET_STATISTICS,
620 &kstats, &
len) > -1) {
621 SCLogDebug(
"(%s) Kernel: Packets %" PRIu32
", dropped %" PRIu32
"",
623 kstats.tp_packets, kstats.tp_drops);
652 struct sockaddr_ll socket_address;
661 if (!PacketIsEthernet(
p)) {
666 const EthernetHdr *ethh = PacketGetEthernet(
p);
668 socket_address.sll_ifindex =
SC_ATOMIC_GET(
p->afp_v.peer->if_idx);
670 socket_address.sll_halen = ETH_ALEN;
672 memcpy(socket_address.sll_addr, ethh, 6);
680 sizeof(
struct sockaddr_ll)) < 0) {
682 SCLogWarning(
"%s: sending packet failed on socket %d: %s",
p->afp_v.peer->iface, socket,
690 static void AFPReleaseDataFromRing(
Packet *
p)
697 AFPWritePacket(
p, TPACKET_V2);
700 BUG_ON(
p->afp_v.relptr == NULL);
703 h.
raw =
p->afp_v.relptr;
706 (void)AFPDerefSocket(
p->afp_v.mpeer);
711 static void AFPReleasePacketV3(
Packet *
p)
718 AFPWritePacket(
p, TPACKET_V3);
723 static void AFPReleasePacket(
Packet *
p)
725 AFPReleaseDataFromRing(
p);
744 #ifdef HAVE_PACKET_EBPF
747 p->afp_v.v4_map_fd = ptv->v4_map_fd;
748 p->afp_v.v6_map_fd = ptv->v6_map_fd;
749 p->afp_v.nr_cpus = ptv->ebpf_t_config.cpus_count;
753 p->afp_v.v4_map_fd = ptv->v4_map_fd;
754 p->afp_v.v6_map_fd = ptv->v6_map_fd;
755 p->afp_v.nr_cpus = ptv->ebpf_t_config.cpus_count;
763 static void AFPReadFromRingSetupPacket(
776 AFPReadApplyBypass(ptv,
p);
778 if (h.
h2->tp_len > h.
h2->tp_snaplen) {
779 SCLogDebug(
"Packet length (%d) > snaplen (%d), truncating", h.
h2->tp_len, h.
h2->tp_snaplen);
788 p->afp_v.vlan_tci = h.
h2->tp_vlan_tci;
794 p->afp_v.relptr = h.
raw;
796 p->afp_v.mpeer = ptv->
mpeer;
797 AFPRefSocket(ptv->
mpeer);
799 p->afp_v.mpeer = NULL;
829 static inline int AFPReadFromRingWaitForPacket(
AFPThreadVars *ptv)
832 struct timeval start_time;
833 gettimeofday(&start_time, NULL);
834 int64_t busy_loop_iter = 0;
845 const unsigned int tp_status = h.
h2->tp_status;
849 struct timeval cur_time;
850 memset(&cur_time, 0,
sizeof(cur_time));
851 uint64_t milliseconds =
852 ((cur_time.tv_sec - start_time.tv_sec) * 1000) +
853 (((1000000 + cur_time.tv_usec - start_time.tv_usec) / 1000) - 1000);
854 if (milliseconds > 1000) {
861 if (busy_loop_iter) {
878 static inline bool AFPShouldIgnoreFrame(
AFPThreadVars *ptv,
const struct sockaddr_ll *sll)
880 if (
unlikely(sll->sll_pkttype > 31))
898 bool emergency_flush =
false;
903 if (AFPReadFromRingWaitForPacket(ptv) !=
AFP_READ_OK)
915 const unsigned int tp_status = h.
h2->tp_status;
931 const struct sockaddr_ll *sll =
932 (
const struct sockaddr_ll *)((uint8_t *)h.
h2 +
933 TPACKET_ALIGN(
sizeof(
struct tpacket2_hdr)));
934 if (
unlikely(AFPShouldIgnoreFrame(ptv, sll)))
939 return AFPSuriFailure(ptv, h);
941 AFPReadFromRingSetupPacket(ptv, h, tp_status,
p);
944 return AFPSuriFailure(ptv, h);
954 if (emergency_flush) {
955 AFPDumpCounters(ptv);
960 static inline void AFPFlushBlock(
struct tpacket_block_desc *pbd)
965 static inline int AFPParsePacketV3(
AFPThreadVars *ptv,
struct tpacket_block_desc *pbd,
struct tpacket3_hdr *ppd)
973 AFPReadApplyBypass(ptv,
p);
981 p->
vlan_id[0] = ppd->hv1.tp_vlan_tci & 0x0fff;
983 p->afp_v.vlan_tci = (uint16_t)ppd->hv1.tp_vlan_tci;
986 if (ppd->tp_len > ppd->tp_snaplen) {
987 SCLogDebug(
"Packet length (%d) > snaplen (%d), truncating", ppd->tp_len, ppd->tp_snaplen);
991 (void)
PacketSetData(
p, (
unsigned char *)ppd + ppd->tp_mac, ppd->tp_snaplen);
994 p->afp_v.relptr = NULL;
995 p->afp_v.mpeer = NULL;
1000 p->
ts = (
SCTime_t){ .
secs = ppd->tp_sec, .usecs = ppd->tp_nsec / 1000 };
1001 SCLogDebug(
"pktlen: %" PRIu32
" (pkt %p, pkt data %p)",
1027 static inline int AFPWalkBlock(
AFPThreadVars *ptv,
struct tpacket_block_desc *pbd)
1029 const int num_pkts = pbd->hdr.bh1.num_pkts;
1030 uint8_t *ppd = (uint8_t *)pbd + pbd->hdr.bh1.offset_to_first_pkt;
1032 for (
int i = 0; i < num_pkts; ++i) {
1033 const struct sockaddr_ll *sll =
1034 (
const struct sockaddr_ll *)(ppd + TPACKET_ALIGN(
sizeof(
struct tpacket3_hdr)));
1035 if (
unlikely(AFPShouldIgnoreFrame(ptv, sll))) {
1036 ppd = ppd + ((
struct tpacket3_hdr *)ppd)->tp_next_offset;
1039 int ret = AFPParsePacketV3(ptv, pbd, (
struct tpacket3_hdr *)ppd);
1052 ppd = ppd + ((
struct tpacket3_hdr *)ppd)->tp_next_offset;
1076 struct tpacket_block_desc *pbd =
1084 int ret = AFPWalkBlock(ptv, pbd);
1105 static int AFPRefSocket(
AFPPeer* peer)
1120 static int AFPDerefSocket(
AFPPeer* peer)
1133 if (ptv->
mpeer != NULL)
1156 static void AFPSwitchState(
AFPThreadVars *ptv, uint8_t state)
1173 static int AFPReadAndDiscardFromRing(
AFPThreadVars *ptv,
struct timeval *synctv,
1174 uint64_t *discarded_pkts)
1182 struct tpacket_block_desc *pbd =
1184 *discarded_pkts += pbd->hdr.bh1.num_pkts;
1185 struct tpacket3_hdr *ppd =
1186 (
struct tpacket3_hdr *)((uint8_t *)pbd + pbd->hdr.bh1.offset_to_first_pkt);
1187 if (((time_t)ppd->tp_sec > synctv->tv_sec) ||
1188 ((time_t)ppd->tp_sec == synctv->tv_sec &&
1189 (suseconds_t) (ppd->tp_nsec / 1000) > (suseconds_t)synctv->tv_usec)) {
1200 if (h.
raw == NULL) {
1206 if (((time_t)h.
h2->tp_sec > synctv->tv_sec) ||
1207 ((time_t)h.
h2->tp_sec == synctv->tv_sec &&
1208 (suseconds_t) (h.
h2->tp_nsec / 1000) > synctv->tv_usec)) {
1212 (*discarded_pkts)++;
1231 static int AFPSynchronizeStart(
AFPThreadVars *ptv, uint64_t *discarded_pkts)
1233 struct timeval synctv;
1237 fds.events = POLLIN;
1240 synctv.tv_sec = 0xffffffff;
1241 synctv.tv_usec = 0xffffffff;
1246 (fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) {
1248 fds.revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL));
1251 if (AFPPeersListStarted() && synctv.tv_sec == (time_t) 0xffffffff) {
1252 gettimeofday(&synctv, NULL);
1254 r = AFPReadAndDiscardFromRing(ptv, &synctv, discarded_pkts);
1264 }
else if (r == 0 && AFPPeersListStarted()) {
1291 AFPCloseSocket(ptv);
1293 int afp_activate_r = AFPCreateSocket(ptv, ptv->
iface, 0);
1294 if (afp_activate_r != 0) {
1298 return afp_activate_r;
1316 time_t last_dump = 0;
1317 time_t current_time;
1319 uint64_t discarded_pkts = 0;
1324 AFPReadFunc = AFPReadFromRingV3;
1326 AFPReadFunc = AFPReadFromRing;
1331 while (AFPPeersListWaitTurn(ptv->
mpeer)) {
1337 r = AFPCreateSocket(ptv, ptv->
iface, 1);
1345 "%s: failed to init socket for interface, retrying soon", ptv->
iface);
1348 AFPPeersListReachedInc();
1352 AFPSynchronizeStart(ptv, &discarded_pkts);
1355 #ifdef PACKET_STATISTICS
1356 struct tpacket_stats kstats;
1357 socklen_t
len =
sizeof (
struct tpacket_stats);
1358 if (getsockopt(ptv->
socket, SOL_PACKET, PACKET_STATISTICS,
1359 &kstats, &
len) > -1) {
1361 SCLogDebug(
"(%s) Kernel socket startup: Packets %" PRIu32
1362 ", dropped %" PRIu32
"",
1364 kstats.tp_packets, kstats.tp_drops);
1365 pkts = kstats.tp_packets - discarded_pkts - kstats.tp_drops;
1373 fds.events = POLLIN;
1390 r = AFPTryReopen(ptv);
1410 (fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) {
1412 if (fds.revents & (POLLHUP | POLLRDHUP)) {
1415 }
else if (fds.revents & POLLERR) {
1418 if (recv(ptv->
socket, &c,
sizeof c, MSG_PEEK) != -1)
1423 }
else if (fds.revents & POLLNVAL) {
1430 r = AFPReadFunc(ptv);
1434 current_time = time(NULL);
1435 if (current_time != last_dump) {
1436 AFPDumpCounters(ptv);
1437 last_dump = current_time;
1449 AFPDumpCounters(ptv);
1455 current_time = time(NULL);
1456 if (current_time != last_dump) {
1457 AFPDumpCounters(ptv);
1458 last_dump = current_time;
1461 TmThreadsCaptureHandleTimeout(
tv, NULL);
1463 }
else if ((r < 0) && (errno != EINTR)) {
1472 AFPDumpCounters(ptv);
1477 static int AFPGetDevFlags(
int fd,
const char *ifname)
1481 memset(&ifr, 0,
sizeof(ifr));
1482 strlcpy(ifr.ifr_name, ifname,
sizeof(ifr.ifr_name));
1484 if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
1485 SCLogError(
"%s: failed to get interface flags: %s", ifname, strerror(errno));
1489 return ifr.ifr_flags;
1493 static int AFPGetIfnumByDev(
int fd,
const char *ifname,
int verbose)
1497 memset(&ifr, 0,
sizeof(ifr));
1498 strlcpy(ifr.ifr_name, ifname,
sizeof(ifr.ifr_name));
1500 if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) {
1502 SCLogError(
"%s: failed to find interface: %s", ifname, strerror(errno));
1506 return ifr.ifr_ifindex;
1509 static int AFPGetDevLinktype(
int fd,
const char *ifname)
1513 memset(&ifr, 0,
sizeof(ifr));
1514 strlcpy(ifr.ifr_name, ifname,
sizeof(ifr.ifr_name));
1516 if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
1517 SCLogError(
"%s: failed to find interface type: %s", ifname, strerror(errno));
1521 switch (ifr.ifr_hwaddr.sa_family) {
1522 case ARPHRD_LOOPBACK:
1528 return ifr.ifr_hwaddr.sa_family;
1536 int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
1538 SCLogError(
"%s: failed to create AF_PACKET socket: %s", ifname, strerror(errno));
1542 ltype = AFPGetDevLinktype(fd, ifname);
1550 static int AFPComputeRingParams(
AFPThreadVars *ptv,
int order)
1576 int tp_hdrlen =
sizeof(
struct tpacket_hdr);
1587 SCLogWarning(
"%s: unable to get MTU, setting snaplen default of 1514", ptv->
iface);
1594 ptv->
req.
v2.tp_frame_size = TPACKET_ALIGN(snaplen +TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) +
sizeof(
struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
1595 ptv->
req.
v2.tp_block_size = getpagesize() << order;
1596 int frames_per_block = ptv->
req.
v2.tp_block_size / ptv->
req.
v2.tp_frame_size;
1597 if (frames_per_block == 0) {
1602 ptv->
req.
v2.tp_block_nr = ptv->
req.
v2.tp_frame_nr / frames_per_block + 1;
1604 ptv->
req.
v2.tp_frame_nr = ptv->
req.
v2.tp_block_nr * frames_per_block;
1605 SCLogPerf(
"%s: rx ring: block_size=%d block_nr=%d frame_size=%d frame_nr=%d", ptv->
iface,
1606 ptv->
req.
v2.tp_block_size, ptv->
req.
v2.tp_block_nr, ptv->
req.
v2.tp_frame_size,
1607 ptv->
req.
v2.tp_frame_nr);
1611 static int AFPComputeRingParamsWithBlockSize(
AFPThreadVars *ptv,
unsigned int block_size)
1637 int tp_hdrlen =
sizeof(
struct tpacket_hdr);
1648 SCLogWarning(
"%s: unable to get MTU, setting snaplen default of 1514", ptv->
iface);
1655 ptv->
req.
v2.tp_frame_size = TPACKET_ALIGN(
1657 TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) +
sizeof(
struct sockaddr_ll) + ETH_HLEN) -
1659 ptv->
req.
v2.tp_block_size = block_size;
1660 int frames_per_block = ptv->
req.
v2.tp_block_size / ptv->
req.
v2.tp_frame_size;
1661 if (frames_per_block == 0) {
1666 ptv->
req.
v2.tp_block_nr = ptv->
req.
v2.tp_frame_nr / frames_per_block + 1;
1668 ptv->
req.
v2.tp_frame_nr = ptv->
req.
v2.tp_block_nr * frames_per_block;
1669 SCLogPerf(
"%s: rx ring: block_size=%d block_nr=%d frame_size=%d frame_nr=%d", ptv->
iface,
1670 ptv->
req.
v2.tp_block_size, ptv->
req.
v2.tp_block_nr, ptv->
req.
v2.tp_frame_size,
1671 ptv->
req.
v2.tp_frame_nr);
1678 ptv->
req.
v3.tp_frame_size = 2048;
1679 int frames_per_block = 0;
1680 int tp_hdrlen =
sizeof(
struct tpacket3_hdr);
1686 SCLogWarning(
"%s: unable to get MTU, setting snaplen default of 1514", ptv->
iface);
1692 ptv->
req.
v3.tp_frame_size = TPACKET_ALIGN(snaplen +TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) +
sizeof(
struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
1693 frames_per_block = ptv->
req.
v3.tp_block_size / ptv->
req.
v3.tp_frame_size;
1695 if (frames_per_block == 0) {
1696 SCLogError(
"%s: block size is too small, it should be at least %d", ptv->
iface,
1697 ptv->
req.
v3.tp_frame_size);
1702 ptv->
req.
v3.tp_frame_nr = ptv->
req.
v3.tp_block_nr * frames_per_block;
1704 ptv->
req.
v3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
1705 SCLogPerf(
"%s: rx ring params: block_size=%d block_nr=%d frame_size=%d frame_nr=%d (mem: %d)",
1707 ptv->
req.
v3.tp_frame_size, ptv->
req.
v3.tp_frame_nr,
1708 ptv->
req.
v3.tp_block_size * ptv->
req.
v3.tp_block_nr);
1715 unsigned int len =
sizeof(val), i;
1724 if (getsockopt(ptv->
socket, SOL_PACKET, PACKET_HDRLEN, &val, &
len) < 0) {
1725 if (errno == ENOPROTOOPT) {
1727 SCLogError(
"%s: kernel too old for TPACKET_V3 (need 3.2+)", devname);
1729 SCLogError(
"%s: kernel too old (need 2.6.27+)", devname);
1732 SCLogError(
"%s: failed to retrieve packet header len", devname);
1740 if (setsockopt(ptv->
socket, SOL_PACKET, PACKET_VERSION, &val,
1742 SCLogError(
"%s: failed to activate TPACKET_V2/TPACKET_V3 on packet socket: %s", devname,
1747 #ifdef HAVE_HW_TIMESTAMPING
1749 int req = SOF_TIMESTAMPING_RAW_HARDWARE;
1750 if (setsockopt(ptv->
socket, SOL_PACKET, PACKET_TIMESTAMP, (
void *)&req,
sizeof(req)) < 0) {
1751 SCLogWarning(
"%s: failed to activate hardware timestamping on packet socket: %s",
1752 devname, strerror(errno));
1754 SCLogConfig(
"%s: hardware timestamping enabled", devname);
1757 SCLogConfig(
"%s: hardware timestamping disabled", devname);
1764 if (setsockopt(ptv->
socket, SOL_PACKET, PACKET_RESERVE, (
void *)&reserve,
sizeof(reserve)) <
1766 SCLogError(
"%s: failed to activate reserve on packet socket: %s", devname, strerror(errno));
1772 if (AFPComputeRingParamsV3(ptv) != 1) {
1775 r = setsockopt(ptv->
socket, SOL_PACKET, PACKET_RX_RING,
1778 SCLogError(
"%s: failed to allocate RX Ring: %s", devname, strerror(errno));
1784 if (AFPComputeRingParamsWithBlockSize(ptv, ptv->
v2_block_size) != 1) {
1785 SCLogError(
"%s: ring parameters are incorrect. Please file a bug report", devname);
1790 ptv->
socket, SOL_PACKET, PACKET_RX_RING, (
void *)&ptv->
req,
sizeof(ptv->
req));
1793 if (errno == ENOMEM) {
1794 SCLogError(
"%s: memory issue with ring parameters", devname);
1797 SCLogError(
"%s: failed to setup RX Ring: %s", devname, strerror(errno));
1803 if (AFPComputeRingParams(ptv, order) != 1) {
1805 "%s: ring parameters are incorrect. Please file a bug report", devname);
1809 r = setsockopt(ptv->
socket, SOL_PACKET, PACKET_RX_RING, (
void *)&ptv->
req,
1813 if (errno == ENOMEM) {
1814 SCLogWarning(
"%s: memory issue with ring parameters. Retrying", devname);
1817 SCLogError(
"%s: failed to setup RX Ring: %s", devname, strerror(errno));
1824 SCLogError(
"%s: failed to setup RX Ring (order 0 failed)", devname);
1836 mmap_flag = MAP_SHARED;
1838 mmap_flag |= MAP_LOCKED;
1840 mmap_flag, ptv->
socket, 0);
1842 SCLogError(
"%s: failed to mmap: %s", devname, strerror(errno));
1848 SCLogError(
"%s: failed to alloc ring: %s", devname, strerror(errno));
1851 for (i = 0; i < ptv->
req.
v3.tp_block_nr; ++i) {
1853 ptv->
ring.
v3[i].iov_len = ptv->
req.
v3.tp_block_size;
1858 if (ptv->
ring.
v2 == NULL) {
1859 SCLogError(
"%s: failed to alloc ring: %s", devname, strerror(errno));
1864 for (i = 0; i < ptv->
req.
v2.tp_block_nr; ++i) {
1865 void *base = &(ptv->
ring_buf[i * ptv->
req.
v2.tp_block_size]);
1869 base += ptv->
req.
v2.tp_frame_size;
1893 #ifdef HAVE_PACKET_FANOUT
1894 int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
1899 uint32_t option = (mode << 16) | cluster_id;
1900 int r = setsockopt(fd, SOL_PACKET,
PACKET_FANOUT,(
void *)&option,
sizeof(option));
1904 SCLogError(
"fanout not supported by kernel: "
1905 "Kernel too old or cluster-id %d already in use.",
1915 #ifdef HAVE_PACKET_EBPF
1919 int pfd = ptv->ebpf_lb_fd;
1921 SCLogError(
"Fanout file descriptor is invalid");
1925 if (setsockopt(ptv->
socket, SOL_PACKET, PACKET_FANOUT_DATA, &pfd,
sizeof(pfd))) {
1936 int pfd = ptv->ebpf_filter_fd;
1938 SCLogError(
"Filter file descriptor is invalid");
1942 if (setsockopt(ptv->
socket, SOL_SOCKET, SO_ATTACH_BPF, &pfd,
sizeof(pfd))) {
1943 SCLogError(
"Error setting ebpf: %s", strerror(errno));
1946 SCLogInfo(
"Activated eBPF filter on socket");
1952 static int AFPCreateSocket(
AFPThreadVars *ptv,
char *devname,
int verbose)
1956 struct packet_mreq sock_params;
1957 struct sockaddr_ll bind_address;
1961 ptv->
socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
1963 SCLogError(
"%s: failed to create socket: %s", devname, strerror(errno));
1967 if_idx = AFPGetIfnumByDev(ptv->
socket, devname, verbose);
1973 memset(&bind_address, 0,
sizeof(bind_address));
1974 bind_address.sll_family = AF_PACKET;
1975 bind_address.sll_protocol = htons(ETH_P_ALL);
1976 bind_address.sll_ifindex = if_idx;
1977 if (bind_address.sll_ifindex == -1) {
1984 int if_flags = AFPGetDevFlags(ptv->
socket, ptv->
iface);
1985 if (if_flags == -1) {
1991 }
else if ((if_flags & (IFF_UP | IFF_RUNNING)) == 0) {
2000 if (if_flags & IFF_LOOPBACK)
2005 memset(&sock_params, 0,
sizeof(sock_params));
2006 sock_params.mr_type = PACKET_MR_PROMISC;
2007 sock_params.mr_ifindex = bind_address.sll_ifindex;
2008 r = setsockopt(ptv->
socket, SOL_PACKET, PACKET_ADD_MEMBERSHIP,(
void *)&sock_params,
sizeof(sock_params));
2010 SCLogError(
"%s: failed to set promisc mode: %s", devname, strerror(errno));
2017 if (setsockopt(ptv->
socket, SOL_PACKET, PACKET_AUXDATA, &val,
2018 sizeof(val)) == -1 && errno != ENOPROTOOPT) {
2020 "%s: 'kernel' checksum mode not supported, falling back to full mode", devname);
2031 if (setsockopt(ptv->
socket, SOL_SOCKET, SO_RCVBUF,
2040 r = bind(ptv->
socket, (
struct sockaddr *)&bind_address,
sizeof(bind_address));
2043 if (errno == ENETDOWN) {
2044 SCLogWarning(
"%s: failed to bind socket, iface is down", devname);
2046 SCLogWarning(
"%s: failed to bind socket: %s", devname, strerror(errno));
2054 #ifdef HAVE_PACKET_FANOUT
2059 uint32_t option = (mode << 16) | (
id & 0xffff);
2062 SCLogError(
"%s: failed to set fanout mode: %s", devname, strerror(errno));
2068 #ifdef HAVE_PACKET_EBPF
2070 r = SockFanoutSeteBPF(ptv);
2072 SCLogError(
"%s: failed to set eBPF: %s", devname, strerror(errno));
2078 ret = AFPSetupRing(ptv, devname);
2082 SCLogDebug(
"Using interface '%s' via socket %d", (
char *)devname, ptv->
socket);
2086 TmEcode rc = AFPSetBPFFilter(ptv);
2117 struct bpf_program filter;
2118 struct sock_fprog fcode;
2121 #ifdef HAVE_PACKET_EBPF
2122 if (ptv->ebpf_filter_fd != -1) {
2123 return SetEbpfFilter(ptv);
2132 char errbuf[PCAP_ERRBUF_SIZE];
2139 errbuf,
sizeof(errbuf)) == -1) {
2144 if (filter.bf_len > USHRT_MAX) {
2147 fcode.len = (
unsigned short)filter.bf_len;
2148 fcode.filter = (
struct sock_filter*)filter.bf_insns;
2150 rc = setsockopt(ptv->
socket, SOL_SOCKET, SO_ATTACH_FILTER, &fcode,
sizeof(fcode));
2154 SCLogError(
"%s: failed to attach filter: %s", ptv->
iface, strerror(errno));
2161 #ifdef HAVE_PACKET_EBPF
2169 static int AFPInsertHalfFlow(
int mapd,
void *key,
unsigned int nr_cpus)
2171 BPF_DECLARE_PERCPU(
struct pair, value, nr_cpus);
2180 for (i = 0; i < nr_cpus; i++) {
2181 BPF_PERCPU(value, i).packets = 0;
2182 BPF_PERCPU(value, i).bytes = 0;
2184 if (bpf_map_update_elem(mapd, key, value, BPF_NOEXIST) != 0) {
2197 SCLogError(
"Can't update eBPF map: %s (%d)", strerror(errno), errno);
2204 static int AFPSetFlowStorage(
Packet *
p,
int map_fd,
void *key0,
void* key1,
2216 EBPFBypassData *eb =
SCCalloc(1,
sizeof(EBPFBypassData));
2218 EBPFDeleteKey(map_fd, key0);
2219 EBPFDeleteKey(map_fd, key1);
2228 eb->cpus_count =
p->afp_v.nr_cpus;
2233 EBPFDeleteKey(map_fd, key0);
2234 EBPFDeleteKey(map_fd, key1);
2246 #define FlowKeyIpFill(k, p) \
2248 (k)->ip_proto = ((p)->proto == IPPROTO_TCP) ? 1 : 0; \
2249 (k)->vlan0 = (p)->vlan_id[0]; \
2250 (k)->vlan1 = (p)->vlan_id[1]; \
2267 static int AFPBypassCallback(
Packet *
p)
2269 SCLogDebug(
"Calling af_packet callback function");
2271 if (!(PacketIsTCP(
p) || PacketIsUDP(
p))) {
2278 if (
p->
flow == NULL) {
2284 if (PacketIsTunnel(
p)) {
2288 if (PacketIsIPv4(
p)) {
2290 if (
p->afp_v.v4_map_fd == -1) {
2293 struct flowv4_keys *keys[2];
2294 keys[0] =
SCCalloc(1,
sizeof(
struct flowv4_keys));
2295 if (keys[0] == NULL) {
2300 FlowKeyIpFill(keys[0],
p);
2301 keys[0]->port16[0] =
p->
sp;
2302 keys[0]->port16[1] =
p->
dp;
2303 if (AFPInsertHalfFlow(
p->afp_v.v4_map_fd, keys[0],
2304 p->afp_v.nr_cpus) == 0) {
2309 keys[1]=
SCCalloc(1,
sizeof(
struct flowv4_keys));
2310 if (keys[1] == NULL) {
2311 EBPFDeleteKey(
p->afp_v.v4_map_fd, keys[0]);
2318 keys[1]->port16[0] =
p->
dp;
2319 keys[1]->port16[1] =
p->
sp;
2320 FlowKeyIpFill(keys[1],
p);
2321 if (AFPInsertHalfFlow(
p->afp_v.v4_map_fd, keys[1],
2322 p->afp_v.nr_cpus) == 0) {
2323 EBPFDeleteKey(
p->afp_v.v4_map_fd, keys[0]);
2329 EBPFUpdateFlow(
p->
flow,
p, NULL);
2330 return AFPSetFlowStorage(
p,
p->afp_v.v4_map_fd, keys[0], keys[1], AF_INET);
2333 if (PacketIsIPv6(
p) && ((
p->
proto == IPPROTO_TCP) || (
p->
proto == IPPROTO_UDP))) {
2335 if (
p->afp_v.v6_map_fd == -1) {
2339 struct flowv6_keys *keys[2];
2340 keys[0] =
SCCalloc(1,
sizeof(
struct flowv6_keys));
2341 if (keys[0] == NULL) {
2345 for (i = 0; i < 4; i++) {
2349 keys[0]->port16[0] =
p->
sp;
2350 keys[0]->port16[1] =
p->
dp;
2351 FlowKeyIpFill(keys[0],
p);
2352 if (AFPInsertHalfFlow(
p->afp_v.v6_map_fd, keys[0],
2353 p->afp_v.nr_cpus) == 0) {
2358 keys[1]=
SCCalloc(1,
sizeof(
struct flowv6_keys));
2359 if (keys[1] == NULL) {
2360 EBPFDeleteKey(
p->afp_v.v6_map_fd, keys[0]);
2365 for (i = 0; i < 4; i++) {
2369 keys[1]->port16[0] =
p->
dp;
2370 keys[1]->port16[1] =
p->
sp;
2371 FlowKeyIpFill(keys[1],
p);
2372 if (AFPInsertHalfFlow(
p->afp_v.v6_map_fd, keys[1],
2373 p->afp_v.nr_cpus) == 0) {
2374 EBPFDeleteKey(
p->afp_v.v6_map_fd, keys[0]);
2381 EBPFUpdateFlow(
p->
flow,
p, NULL);
2382 return AFPSetFlowStorage(
p,
p->afp_v.v6_map_fd, keys[0], keys[1], AF_INET6);
2398 static int AFPXDPBypassCallback(
Packet *
p)
2400 SCLogDebug(
"Calling af_packet callback function");
2402 if (!(PacketIsTCP(
p) || PacketIsUDP(
p))) {
2409 if (
p->
flow == NULL) {
2415 if (PacketIsTunnel(
p)) {
2419 if (PacketIsIPv4(
p)) {
2420 struct flowv4_keys *keys[2];
2421 keys[0]=
SCCalloc(1,
sizeof(
struct flowv4_keys));
2422 if (keys[0] == NULL) {
2426 if (
p->afp_v.v4_map_fd == -1) {
2430 keys[0]->src =
p->
src.addr_data32[0];
2431 keys[0]->dst =
p->
dst.addr_data32[0];
2434 keys[0]->port16[0] = htons(
p->
sp);
2435 keys[0]->port16[1] = htons(
p->
dp);
2436 FlowKeyIpFill(keys[0],
p);
2437 if (AFPInsertHalfFlow(
p->afp_v.v4_map_fd, keys[0],
2438 p->afp_v.nr_cpus) == 0) {
2443 keys[1]=
SCCalloc(1,
sizeof(
struct flowv4_keys));
2444 if (keys[1] == NULL) {
2445 EBPFDeleteKey(
p->afp_v.v4_map_fd, keys[0]);
2450 keys[1]->src =
p->
dst.addr_data32[0];
2451 keys[1]->dst =
p->
src.addr_data32[0];
2452 keys[1]->port16[0] = htons(
p->
dp);
2453 keys[1]->port16[1] = htons(
p->
sp);
2454 FlowKeyIpFill(keys[1],
p);
2455 if (AFPInsertHalfFlow(
p->afp_v.v4_map_fd, keys[1],
2456 p->afp_v.nr_cpus) == 0) {
2457 EBPFDeleteKey(
p->afp_v.v4_map_fd, keys[0]);
2463 return AFPSetFlowStorage(
p,
p->afp_v.v4_map_fd, keys[0], keys[1], AF_INET);
2466 if (PacketIsIPv6(
p) && ((
p->
proto == IPPROTO_TCP) || (
p->
proto == IPPROTO_UDP))) {
2468 if (
p->afp_v.v6_map_fd == -1) {
2472 struct flowv6_keys *keys[2];
2473 keys[0] =
SCCalloc(1,
sizeof(
struct flowv6_keys));
2474 if (keys[0] == NULL) {
2478 for (i = 0; i < 4; i++) {
2482 keys[0]->port16[0] = htons(
p->
sp);
2483 keys[0]->port16[1] = htons(
p->
dp);
2484 FlowKeyIpFill(keys[0],
p);
2485 if (AFPInsertHalfFlow(
p->afp_v.v6_map_fd, keys[0],
2486 p->afp_v.nr_cpus) == 0) {
2491 keys[1]=
SCCalloc(1,
sizeof(
struct flowv6_keys));
2492 if (keys[1] == NULL) {
2493 EBPFDeleteKey(
p->afp_v.v6_map_fd, keys[0]);
2498 for (i = 0; i < 4; i++) {
2502 keys[1]->port16[0] = htons(
p->
dp);
2503 keys[1]->port16[1] = htons(
p->
sp);
2504 FlowKeyIpFill(keys[1],
p);
2505 if (AFPInsertHalfFlow(
p->afp_v.v6_map_fd, keys[1],
2506 p->afp_v.nr_cpus) == 0) {
2507 EBPFDeleteKey(
p->afp_v.v6_map_fd, keys[0]);
2513 return AFPSetFlowStorage(
p,
p->afp_v.v6_map_fd, keys[0], keys[1], AF_INET6);
2518 bool g_flowv4_ok =
true;
2519 bool g_flowv6_ok =
true;
2537 if (initdata == NULL) {
2571 #ifdef HAVE_PACKET_FANOUT
2586 #ifdef HAVE_PACKET_EBPF
2589 ptv->xdp_mode = afpconfig->
xdp_mode;
2593 ptv->v4_map_fd = EBPFGetMapFDByName(ptv->
iface,
"flow_table_v4");
2594 if (ptv->v4_map_fd == -1) {
2596 SCLogError(
"Can't find eBPF map fd for '%s'",
"flow_table_v4");
2597 g_flowv4_ok =
false;
2600 ptv->v6_map_fd = EBPFGetMapFDByName(ptv->
iface,
"flow_table_v6");
2601 if (ptv->v6_map_fd == -1) {
2603 SCLogError(
"Can't find eBPF map fd for '%s'",
"flow_table_v6");
2604 g_flowv6_ok =
false;
2608 ptv->ebpf_t_config = afpconfig->ebpf_t_config;
2611 #ifdef PACKET_STATISTICS
2637 SCLogWarning(
"Enabling a BPF filter in IPS mode result"
2638 " in dropping all non matching packets.");
2649 *data = (
void *)ptv;
2668 void ReceiveAFPThreadExitStats(
ThreadVars *
tv,
void *data)
2673 #ifdef PACKET_STATISTICS
2674 AFPDumpCounters(ptv);
2692 #ifdef HAVE_PACKET_XDP
2693 if ((ptv->ebpf_t_config.
flags & EBPF_XDP_CODE) &&
2694 (!(ptv->ebpf_t_config.
flags & EBPF_PINNED_MAPS))) {
2695 EBPFSetupXDP(ptv->
iface, -1, ptv->xdp_mode);
2721 static void UpdateRawDataForVLANHdr(
Packet *
p)
2723 if (
p->afp_v.vlan_tci != 0) {
2729 *(uint16_t *)(pstart + 2 * ETH_ALEN) = htons(0x8100);
2730 *(uint16_t *)(pstart + 2 * ETH_ALEN + 2) = htons(
p->afp_v.vlan_tci);
2753 const bool afp_vlan_hdr =
p->
vlan_idx != 0;
2766 UpdateRawDataForVLANHdr(
p);
2783 *data = (
void *)
dtv;