• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jasonish / suricata / 23262806180

18 Mar 2026 07:20PM UTC coverage: 79.32% (+0.02%) from 79.297%
23262806180

push

github

jasonish
github-ci/builds: update ubuntu builds to rust 1.89

266068 of 335437 relevant lines covered (79.32%)

4677245.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

63.05
/src/source-af-packet.c
1
/* Copyright (C) 2011-2021 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17

18
/**
19
 *  \defgroup afppacket AF_PACKET running mode
20
 *
21
 *  @{
22
 */
23

24
/**
25
 * \file
26
 *
27
 * \author Eric Leblond <eric@regit.org>
28
 *
29
 * AF_PACKET socket acquisition support
30
 *
31
 */
32

33
#define SC_PCAP_DONT_INCLUDE_PCAP_H 1
34
#include "suricata-common.h"
35
#include "suricata.h"
36
#include "packet.h"
37
#include "decode.h"
38
#include "packet-queue.h"
39
#include "threads.h"
40
#include "threadvars.h"
41
#include "tm-queuehandlers.h"
42
#include "tm-modules.h"
43
#include "tm-threads.h"
44
#include "tm-threads-common.h"
45
#include "conf.h"
46
#include "util-cpu.h"
47
#include "util-datalink.h"
48
#include "util-debug.h"
49
#include "util-device-private.h"
50
#include "util-ebpf.h"
51
#include "util-error.h"
52
#include "util-privs.h"
53
#include "util-optimize.h"
54
#include "util-checksum.h"
55
#include "util-ioctl.h"
56
#include "util-host-info.h"
57
#include "tmqh-packetpool.h"
58
#include "source-af-packet.h"
59
#include "runmodes.h"
60
#include "flow-storage.h"
61
#include "util-validate.h"
62
#include "action-globals.h"
63

64
#ifdef HAVE_AF_PACKET
65

66
#if HAVE_SYS_IOCTL_H
67
#include <sys/ioctl.h>
68
#endif
69

70
#if HAVE_LINUX_SOCKIOS_H
71
#include <linux/sockios.h>
72
#endif
73

74
#ifdef HAVE_PACKET_EBPF
75
#define PCAP_DONT_INCLUDE_PCAP_BPF_H 1
76
#include <bpf/libbpf.h>
77
#include <bpf/bpf.h>
78

79
struct bpf_program {
80
    unsigned int bf_len;
81
    struct bpf_insn *bf_insns;
82
};
83
#endif
84

85
#ifdef HAVE_PCAP_H
86
#include <pcap.h>
87
#endif
88

89
#ifdef HAVE_PCAP_PCAP_H
90
#include <pcap/pcap.h>
91
#endif
92

93
#include "util-bpf.h"
94

95
#if HAVE_LINUX_IF_ETHER_H
96
#include <linux/if_ether.h>
97
#endif
98

99
#if HAVE_LINUX_IF_PACKET_H
100
#include <linux/if_packet.h>
101
#endif
102

103
#if HAVE_LINUX_IF_ARP_H
104
#include <linux/if_arp.h>
105
#endif
106

107
#if HAVE_LINUX_FILTER_H
108
#include <linux/filter.h>
109
#endif
110

111
#if HAVE_SYS_MMAN_H
112
#include <sys/mman.h>
113
#endif
114

115
#ifdef HAVE_HW_TIMESTAMPING
116
#include <linux/net_tstamp.h>
117
#endif
118

119
#endif /* HAVE_AF_PACKET */
120

121
extern uint32_t max_pending_packets;
122

123
#ifndef HAVE_AF_PACKET
124

125
TmEcode NoAFPSupportExit(ThreadVars *, const void *, void **);
126

127
void TmModuleReceiveAFPRegister (void)
128
{
129
    tmm_modules[TMM_RECEIVEAFP].name = "ReceiveAFP";
130
    tmm_modules[TMM_RECEIVEAFP].ThreadInit = NoAFPSupportExit;
131
    tmm_modules[TMM_RECEIVEAFP].Func = NULL;
132
    tmm_modules[TMM_RECEIVEAFP].ThreadExitPrintStats = NULL;
133
    tmm_modules[TMM_RECEIVEAFP].ThreadDeinit = NULL;
134
    tmm_modules[TMM_RECEIVEAFP].cap_flags = 0;
135
    tmm_modules[TMM_RECEIVEAFP].flags = TM_FLAG_RECEIVE_TM;
136
}
137

138
/**
139
 * \brief Registration Function for DecodeAFP.
140
 */
141
void TmModuleDecodeAFPRegister (void)
142
{
143
    tmm_modules[TMM_DECODEAFP].name = "DecodeAFP";
144
    tmm_modules[TMM_DECODEAFP].ThreadInit = NoAFPSupportExit;
145
    tmm_modules[TMM_DECODEAFP].Func = NULL;
146
    tmm_modules[TMM_DECODEAFP].ThreadExitPrintStats = NULL;
147
    tmm_modules[TMM_DECODEAFP].ThreadDeinit = NULL;
148
    tmm_modules[TMM_DECODEAFP].cap_flags = 0;
149
    tmm_modules[TMM_DECODEAFP].flags = TM_FLAG_DECODE_TM;
150
}
151

152
/**
153
 * \brief this function prints an error message and exits.
154
 */
155
TmEcode NoAFPSupportExit(ThreadVars *tv, const void *initdata, void **data)
156
{
157
    SCLogError("Error creating thread %s: you do not have "
158
               "support for AF_PACKET enabled, on Linux host please recompile "
159
               "with --enable-af-packet",
160
            tv->name);
161
    exit(EXIT_FAILURE);
162
}
163

164
#else /* We have AF_PACKET support */
165

166
#define AFP_IFACE_NAME_LENGTH 48
168✔
167

168
#define AFP_STATE_DOWN 0
160✔
169
#define AFP_STATE_UP 1
160✔
170

171
#define AFP_RECONNECT_TIMEOUT 500000
×
172
#define AFP_DOWN_COUNTER_INTERVAL 40
×
173

174
#define POLL_TIMEOUT 100
32,294✔
175

176
/* kernel flags defined for RX ring tp_status */
177
#ifndef TP_STATUS_KERNEL
178
#define TP_STATUS_KERNEL 0
179
#endif
180
#ifndef TP_STATUS_USER
181
#define TP_STATUS_USER BIT_U32(0)
182
#endif
183
#ifndef TP_STATUS_COPY
184
#define TP_STATUS_COPY BIT_U32(1)
185
#endif
186
#ifndef TP_STATUS_LOSING
187
#define TP_STATUS_LOSING BIT_U32(2)
188
#endif
189
#ifndef TP_STATUS_CSUMNOTREADY
190
#define TP_STATUS_CSUMNOTREADY BIT_U32(3)
191
#endif
192
#ifndef TP_STATUS_VLAN_VALID
193
#define TP_STATUS_VLAN_VALID BIT_U32(4)
194
#endif
195
#ifndef TP_STATUS_BLK_TMO
196
#define TP_STATUS_BLK_TMO BIT_U32(5)
197
#endif
198
#ifndef TP_STATUS_VLAN_TPID_VALID
199
#define TP_STATUS_VLAN_TPID_VALID BIT_U32(6)
200
#endif
201
#ifndef TP_STATUS_CSUM_VALID
202
#define TP_STATUS_CSUM_VALID BIT_U32(7)
203
#endif
204

205
#ifndef TP_STATUS_TS_SOFTWARE
206
#define TP_STATUS_TS_SOFTWARE BIT_U32(29)
207
#endif
208
#ifndef TP_STATUS_TS_SYS_HARDWARE
209
#define TP_STATUS_TS_SYS_HARDWARE BIT_U32(30) /* kernel comment says: "deprecated, never set" */
210
#endif
211
#ifndef TP_STATUS_TS_RAW_HARDWARE
212
#define TP_STATUS_TS_RAW_HARDWARE BIT_U32(31)
213
#endif
214

215
#ifndef TP_STATUS_USER_BUSY
216
/* HACK special setting in the tp_status field for frames we are
217
 * still working on. This can happen in autofp mode where the
218
 * capture thread goes around the ring and finds a frame that still
219
 * hasn't been released by a worker thread.
220
 *
221
 * We use bits 29, 30, 31. 29 and 31 are software and hardware
222
 * timestamps. 30 should not be set by the kernel at all. Combined
223
 * they should never be set on the rx-ring together.
224
 *
225
 * The excessive casting is for handling the fact that the kernel
226
 * defines almost all of these as int flags, not unsigned ints. */
227
#define TP_STATUS_USER_BUSY                                                                        \
228
    (uint32_t)((uint32_t)TP_STATUS_TS_SOFTWARE | (uint32_t)TP_STATUS_TS_SYS_HARDWARE |             \
19,435✔
229
               (uint32_t)TP_STATUS_TS_RAW_HARDWARE)
19,435✔
230
#endif
231
#define FRAME_BUSY(tp_status)                                                                      \
232
    (((uint32_t)(tp_status) & (uint32_t)TP_STATUS_USER_BUSY) == (uint32_t)TP_STATUS_USER_BUSY)
233

234
enum {
235
    AFP_READ_OK,
236
    AFP_READ_FAILURE,
237
    /** Error during treatment by other functions of Suricata */
238
    AFP_SURI_FAILURE,
239
    AFP_KERNEL_DROP,
240
};
241

242
enum {
243
    AFP_FATAL_ERROR = 1,
244
    AFP_RECOVERABLE_ERROR,
245
};
246

247
union thdr {
248
    struct tpacket2_hdr *h2;
249
    struct tpacket3_hdr *h3;
250
    void *raw;
251
};
252

253
#ifdef HAVE_PACKET_EBPF
254
static int AFPBypassCallback(Packet *p);
255
static int AFPXDPBypassCallback(Packet *p);
256
#endif
257

258
/**
259
 * \brief Structure to hold thread specific variables.
260
 */
261
typedef struct AFPThreadVars_
262
{
263
    union AFPRing {
264
        union thdr **v2;
265
        struct iovec *v3;
266
    } ring;
267

268
    /* counters */
269
    uint64_t pkts;
270

271
    ThreadVars *tv;
272
    TmSlot *slot;
273
    LiveDevice *livedev;
274
    /* data link type for the thread */
275
    uint32_t datalink;
276

277
#ifdef HAVE_PACKET_EBPF
278
    /* File descriptor of the IPv4 flow bypass table maps */
279
    int v4_map_fd;
280
    /* File descriptor of the IPv6 flow bypass table maps */
281
    int v6_map_fd;
282
#endif
283

284
    unsigned int frame_offset;
285

286
    ChecksumValidationMode checksum_mode;
287

288
    /* references to packet and drop counters */
289
    StatsCounterId capture_kernel_packets;
290
    StatsCounterId capture_kernel_drops;
291
    StatsCounterId capture_errors;
292
    StatsCounterAvgId afpacket_spin;
293
    StatsCounterId capture_afp_poll;
294
    StatsCounterId capture_afp_poll_signal;
295
    StatsCounterId capture_afp_poll_timeout;
296
    StatsCounterId capture_afp_poll_data;
297
    StatsCounterId capture_afp_poll_err;
298
    StatsCounterId capture_afp_send_err;
299

300
    int64_t send_errors_logged; /**< snapshot of send errors logged. */
301

302
    /* handle state */
303
    uint8_t afp_state;
304
    uint8_t copy_mode;
305
    unsigned int flags;
306

307
    /* IPS peer */
308
    AFPPeer *mpeer;
309

310
    /*
311
     *  Init related members
312
     */
313

314
    /* thread specific socket */
315
    int socket;
316

317
    int ring_size;
318
    int v2_block_size;
319
    int block_size;
320
    int block_timeout;
321
    /* socket buffer size */
322
    int buffer_size;
323
    /* Filter */
324
    const char *bpf_filter;
325

326
    int promisc;
327

328
    /* bitmask of ignored ssl_pkttypes */
329
    uint32_t pkttype_filter_mask;
330

331
    int down_count;
332

333
    uint16_t cluster_id;
334
    int cluster_type;
335

336
    int threads;
337

338
    union AFPTpacketReq {
339
        struct tpacket_req v2;
340
        struct tpacket_req3 v3;
341
    } req;
342

343
    char iface[AFP_IFACE_NAME_LENGTH];
344
    /* IPS output iface */
345
    char out_iface[AFP_IFACE_NAME_LENGTH];
346

347
    /* mmap'ed ring buffer */
348
    unsigned int ring_buflen;
349
    uint8_t *ring_buf;
350

351
    int snaplen; /**< snaplen in use for passing on to bpf */
352
#ifdef HAVE_PACKET_EBPF
353
    uint8_t xdp_mode;
354
    int ebpf_lb_fd;
355
    int ebpf_filter_fd;
356
    struct ebpf_timeout_config ebpf_t_config;
357
#endif
358

359
} AFPThreadVars;
360

361
static TmEcode ReceiveAFPThreadInit(ThreadVars *, const void *, void **);
362
static void ReceiveAFPThreadExitStats(ThreadVars *, void *);
363
static TmEcode ReceiveAFPThreadDeinit(ThreadVars *, void *);
364
static TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot);
365

366
static TmEcode DecodeAFPThreadInit(ThreadVars *, const void *, void **);
367
static TmEcode DecodeAFPThreadDeinit(ThreadVars *tv, void *data);
368
static TmEcode DecodeAFP(ThreadVars *, Packet *, void *);
369

370
static TmEcode AFPSetBPFFilter(AFPThreadVars *ptv);
371
static int AFPGetIfnumByDev(int fd, const char *ifname, int verbose);
372
static int AFPGetDevFlags(int fd, const char *ifname);
373
static int AFPDerefSocket(AFPPeer* peer);
374
static int AFPRefSocket(AFPPeer* peer);
375

376

377
/**
378
 * \brief Registration Function for RecieveAFP.
379
 * \todo Unit tests are needed for this module.
380
 */
381
void TmModuleReceiveAFPRegister (void)
382
{
2,223✔
383
    tmm_modules[TMM_RECEIVEAFP].name = "ReceiveAFP";
2,223✔
384
    tmm_modules[TMM_RECEIVEAFP].ThreadInit = ReceiveAFPThreadInit;
2,223✔
385
    tmm_modules[TMM_RECEIVEAFP].Func = NULL;
2,223✔
386
    tmm_modules[TMM_RECEIVEAFP].PktAcqLoop = ReceiveAFPLoop;
2,223✔
387
    tmm_modules[TMM_RECEIVEAFP].PktAcqBreakLoop = NULL;
2,223✔
388
    tmm_modules[TMM_RECEIVEAFP].ThreadExitPrintStats = ReceiveAFPThreadExitStats;
2,223✔
389
    tmm_modules[TMM_RECEIVEAFP].ThreadDeinit = ReceiveAFPThreadDeinit;
2,223✔
390
    tmm_modules[TMM_RECEIVEAFP].cap_flags = SC_CAP_NET_RAW;
2,223✔
391
    tmm_modules[TMM_RECEIVEAFP].flags = TM_FLAG_RECEIVE_TM;
2,223✔
392

393
}
2,223✔
394

395
/**
396
 *  \defgroup afppeers AFP peers list
397
 *
398
 * AF_PACKET has an IPS mode were interface are peered: packet from
399
 * on interface are sent the peered interface and the other way. The ::AFPPeer
400
 * list is maintaining the list of peers. Each ::AFPPeer is storing the needed
401
 * information to be able to send packet on the interface.
402
 * A element of the list must not be destroyed during the run of Suricata as it
403
 * is used by ::Packet and other threads.
404
 *
405
 *  @{
406
 */
407

408
typedef struct AFPPeersList_ {
409
    TAILQ_HEAD(, AFPPeer_) peers; /**< Head of list of fragments. */
410
    int cnt;
411
    int peered;
412
    int turn; /**< Next value for initialisation order */
413
    SC_ATOMIC_DECLARE(int, reached); /**< Counter used to synchronize start */
414
} AFPPeersList;
415

416
/**
417
 * \brief Update the peer.
418
 *
419
 * Update the AFPPeer of a thread ie set new state, socket number
420
 * or iface index.
421
 *
422
 */
423
static void AFPPeerUpdate(AFPThreadVars *ptv)
424
{
80✔
425
    if (ptv->mpeer == NULL) {
80✔
426
        return;
×
427
    }
×
428
    (void)SC_ATOMIC_SET(ptv->mpeer->if_idx, AFPGetIfnumByDev(ptv->socket, ptv->iface, 0));
80✔
429
    (void)SC_ATOMIC_SET(ptv->mpeer->socket, ptv->socket);
80✔
430
    (void)SC_ATOMIC_SET(ptv->mpeer->state, ptv->afp_state);
80✔
431
}
80✔
432

433
/**
434
 * \brief Clean and free ressource used by an ::AFPPeer
435
 */
436
static void AFPPeerClean(AFPPeer *peer)
437
{
40✔
438
    if (peer->flags & AFP_SOCK_PROTECT)
40✔
439
        SCMutexDestroy(&peer->sock_protect);
12✔
440
    SCFree(peer);
40✔
441
}
40✔
442

443
AFPPeersList peerslist;
444

445

446
/**
447
 * \brief Init the global list of ::AFPPeer
448
 */
449
TmEcode AFPPeersListInit(void)
450
{
8✔
451
    SCEnter();
8✔
452
    TAILQ_INIT(&peerslist.peers);
8✔
453
    peerslist.peered = 0;
8✔
454
    peerslist.cnt = 0;
8✔
455
    peerslist.turn = 0;
8✔
456
    SC_ATOMIC_INIT(peerslist.reached);
8✔
457
    (void) SC_ATOMIC_SET(peerslist.reached, 0);
8✔
458
    SCReturnInt(TM_ECODE_OK);
8✔
459
}
8✔
460

461
/**
462
 * \brief Check that all ::AFPPeer got a peer
463
 *
464
 * \retval TM_ECODE_FAILED if some threads are not peered or TM_ECODE_OK else.
465
 */
466
TmEcode AFPPeersListCheck(void)
467
{
8✔
468
#define AFP_PEERS_MAX_TRY 4
8✔
469
#define AFP_PEERS_WAIT 20000
8✔
470
    int try = 0;
8✔
471
    SCEnter();
8✔
472
    while (try < AFP_PEERS_MAX_TRY) {
8✔
473
        if (peerslist.cnt != peerslist.peered) {
8✔
474
            usleep(AFP_PEERS_WAIT);
×
475
        } else {
8✔
476
            SCReturnInt(TM_ECODE_OK);
8✔
477
        }
8✔
478
        try++;
×
479
    }
×
480
    SCLogError("thread number not equal");
×
481
    SCReturnInt(TM_ECODE_FAILED);
×
482
}
8✔
483

484
/**
485
 * \brief Declare a new AFP thread to AFP peers list.
486
 */
487
static TmEcode AFPPeersListAdd(AFPThreadVars *ptv)
488
{
40✔
489
    SCEnter();
40✔
490
    AFPPeer *peer = SCCalloc(1, sizeof(AFPPeer));
40✔
491
    AFPPeer *pitem;
40✔
492

493
    if (unlikely(peer == NULL)) {
40✔
494
        SCReturnInt(TM_ECODE_FAILED);
×
495
    }
×
496
    SC_ATOMIC_INIT(peer->socket);
40✔
497
    SC_ATOMIC_INIT(peer->sock_usage);
40✔
498
    SC_ATOMIC_INIT(peer->if_idx);
40✔
499
    SC_ATOMIC_INIT(peer->state);
40✔
500
    peer->flags = ptv->flags;
40✔
501
    peer->turn = peerslist.turn++;
40✔
502

503
    if (peer->flags & AFP_SOCK_PROTECT) {
40✔
504
        SCMutexInit(&peer->sock_protect, NULL);
12✔
505
    }
12✔
506

507
    (void)SC_ATOMIC_SET(peer->sock_usage, 0);
40✔
508
    (void)SC_ATOMIC_SET(peer->state, AFP_STATE_DOWN);
40✔
509
    strlcpy(peer->iface, ptv->iface, AFP_IFACE_NAME_LENGTH);
40✔
510
    ptv->mpeer = peer;
40✔
511
    /* add element to iface list */
512
    TAILQ_INSERT_TAIL(&peerslist.peers, peer, next);
40✔
513

514
    if (ptv->copy_mode != AFP_COPY_MODE_NONE) {
40✔
515
        peerslist.cnt++;
24✔
516

517
        /* Iter to find a peer */
518
        TAILQ_FOREACH(pitem, &peerslist.peers, next) {
76✔
519
            if (pitem->peer)
76✔
520
                continue;
42✔
521
            if (strcmp(pitem->iface, ptv->out_iface))
34✔
522
                continue;
22✔
523
            peer->peer = pitem;
12✔
524
            pitem->peer = peer;
12✔
525

526
            LiveDevice *iface = ptv->livedev;
12✔
527
            DEBUG_VALIDATE_BUG_ON(iface == NULL);
12✔
528
            DEBUG_VALIDATE_BUG_ON(strcmp(iface->dev, ptv->iface) != 0);
12✔
529
            LiveDevice *out_iface = LiveGetDevice(ptv->out_iface);
12✔
530
            if (out_iface == NULL)
12✔
531
                FatalError("AF_PACKET device %s not found. Aborting..", ptv->out_iface);
×
532
            if (iface->mtu != out_iface->mtu) {
12✔
533
                SCLogWarning("MTU on %s (%d) and %s (%d) are not equal, transmission of packets "
×
534
                             "bigger than %d will fail.",
×
535
                        iface->dev, iface->mtu, out_iface->dev, out_iface->mtu,
×
536
                        MIN(out_iface->mtu, iface->mtu));
×
537
            }
×
538
            peerslist.peered += 2;
12✔
539
            break;
12✔
540
        }
12✔
541
    }
24✔
542

543
    AFPPeerUpdate(ptv);
40✔
544

545
    SCReturnInt(TM_ECODE_OK);
40✔
546
}
40✔
547

548
static int AFPPeersListWaitTurn(AFPPeer *peer)
549
{
925✔
550
    /* If turn is zero, we already have started threads once */
551
    if (peerslist.turn == 0)
925✔
552
        return 0;
×
553

554
    if (peer->turn == SC_ATOMIC_GET(peerslist.reached))
925✔
555
        return 0;
40✔
556
    return 1;
885✔
557
}
925✔
558

559
static void AFPPeersListReachedInc(void)
560
{
40✔
561
    if (peerslist.turn == 0)
40✔
562
        return;
×
563

564
    if ((SC_ATOMIC_ADD(peerslist.reached, 1) + 1) == peerslist.turn) {
40✔
565
        (void)SC_ATOMIC_SET(peerslist.reached, 0);
8✔
566
        /* Set turn to 0 to skip synchronization when ReceiveAFPLoop is
567
         * restarted.
568
         */
569
        peerslist.turn = 0;
8✔
570
    }
8✔
571
}
40✔
572

573
static int AFPPeersListStarted(void)
574
{
42✔
575
    return !peerslist.turn;
42✔
576
}
42✔
577

578
/**
579
 * \brief Clean the global peers list.
580
 */
581
void AFPPeersListClean(void)
582
{
2,140✔
583
    AFPPeer *pitem;
2,140✔
584

585
    while ((pitem = TAILQ_FIRST(&peerslist.peers))) {
2,180✔
586
        TAILQ_REMOVE(&peerslist.peers, pitem, next);
40✔
587
        AFPPeerClean(pitem);
40✔
588
    }
40✔
589
}
2,140✔
590

591
/**
592
 * @}
593
 */
594

595
/**
596
 * \brief Registration Function for DecodeAFP.
597
 * \todo Unit tests are needed for this module.
598
 */
599
void TmModuleDecodeAFPRegister (void)
600
{
2,223✔
601
    tmm_modules[TMM_DECODEAFP].name = "DecodeAFP";
2,223✔
602
    tmm_modules[TMM_DECODEAFP].ThreadInit = DecodeAFPThreadInit;
2,223✔
603
    tmm_modules[TMM_DECODEAFP].Func = DecodeAFP;
2,223✔
604
    tmm_modules[TMM_DECODEAFP].ThreadExitPrintStats = NULL;
2,223✔
605
    tmm_modules[TMM_DECODEAFP].ThreadDeinit = DecodeAFPThreadDeinit;
2,223✔
606
    tmm_modules[TMM_DECODEAFP].cap_flags = 0;
2,223✔
607
    tmm_modules[TMM_DECODEAFP].flags = TM_FLAG_DECODE_TM;
2,223✔
608
}
2,223✔
609

610
static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose, const bool peer_update);
611

612
static inline void AFPDumpCounters(AFPThreadVars *ptv)
613
{
2,427✔
614
#ifdef PACKET_STATISTICS
2,427✔
615
    struct tpacket_stats kstats;
2,427✔
616
    socklen_t len = sizeof (struct tpacket_stats);
2,427✔
617
    if (getsockopt(ptv->socket, SOL_PACKET, PACKET_STATISTICS,
2,427✔
618
                &kstats, &len) > -1) {
2,429✔
619
        SCLogDebug("(%s) Kernel: Packets %" PRIu32 ", dropped %" PRIu32 "",
2,429✔
620
                ptv->tv->name,
2,429✔
621
                kstats.tp_packets, kstats.tp_drops);
2,429✔
622
        StatsCounterAddI64(&ptv->tv->stats, ptv->capture_kernel_packets, kstats.tp_packets);
2,429✔
623
        StatsCounterAddI64(&ptv->tv->stats, ptv->capture_kernel_drops, kstats.tp_drops);
2,429✔
624
        (void) SC_ATOMIC_ADD(ptv->livedev->drop, (uint64_t) kstats.tp_drops);
2,429✔
625
        (void) SC_ATOMIC_ADD(ptv->livedev->pkts, (uint64_t) kstats.tp_packets);
2,429✔
626

627
        const int64_t value = SC_ATOMIC_GET(ptv->mpeer->send_errors);
2,429✔
628
        if (value > ptv->send_errors_logged) {
2,429✔
629
            StatsCounterAddI64(
×
630
                    &ptv->tv->stats, ptv->capture_afp_send_err, value - ptv->send_errors_logged);
×
631
            ptv->send_errors_logged = value;
×
632
        }
×
633
    }
2,429✔
634
#endif
2,427✔
635
}
2,427✔
636

637
/**
638
 * \brief AF packet write function.
639
 *
640
 * This function has to be called before the memory
641
 * related to Packet in ring buffer is released.
642
 *
643
 * \param pointer to Packet
644
 * \param version of capture: TPACKET_V2 or TPACKET_V3
645
 * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
646
 *
647
 */
648
static void AFPWritePacket(Packet *p, int version)
649
{
19,133✔
650
    struct sockaddr_ll socket_address;
19,133✔
651
    int socket;
19,133✔
652

653
    if (p->afp_v.copy_mode == AFP_COPY_MODE_IPS) {
19,133✔
654
        if (PacketCheckAction(p, ACTION_DROP)) {
19,133✔
655
            return;
50✔
656
        }
50✔
657
    }
19,133✔
658

659
    if (!PacketIsEthernet(p)) {
19,083✔
660
        SCLogWarning("packet should have an ethernet header");
×
661
        return;
×
662
    }
×
663

664
    const EthernetHdr *ethh = PacketGetEthernet(p);
19,083✔
665
    /* Index of the network device */
666
    socket_address.sll_ifindex = SC_ATOMIC_GET(p->afp_v.peer->if_idx);
19,083✔
667
    /* Address length*/
668
    socket_address.sll_halen = ETH_ALEN;
19,083✔
669
    /* Destination MAC */
670
    memcpy(socket_address.sll_addr, ethh, 6);
19,083✔
671

672
    /* Send packet, locking the socket if necessary */
673
    if (p->afp_v.peer->flags & AFP_SOCK_PROTECT)
19,083✔
674
        SCMutexLock(&p->afp_v.peer->sock_protect);
69✔
675
    socket = SC_ATOMIC_GET(p->afp_v.peer->socket);
19,083✔
676

677
    if (sendto(socket, GET_PKT_DATA(p), GET_PKT_LEN(p), 0, (struct sockaddr *)&socket_address,
19,083✔
678
                sizeof(struct sockaddr_ll)) < 0) {
19,083✔
679
        if (SC_ATOMIC_ADD(p->afp_v.peer->send_errors, 1) == 0) {
×
680
            SCLogWarning("%s: sending packet failed on socket %d: %s", p->afp_v.peer->iface, socket,
×
681
                    strerror(errno));
×
682
        }
×
683
    }
×
684
    if (p->afp_v.peer->flags & AFP_SOCK_PROTECT)
19,083✔
685
        SCMutexUnlock(&p->afp_v.peer->sock_protect);
69✔
686
}
19,083✔
687

688
static void AFPReleaseDataFromRing(Packet *p)
689
{
19,435✔
690
    DEBUG_VALIDATE_BUG_ON(PKT_IS_PSEUDOPKT(p));
19,435✔
691

692
    /* Need to be in copy mode and need to detect early release
693
       where Ethernet header could not be set (and pseudo packet) */
694
    if (p->afp_v.copy_mode != AFP_COPY_MODE_NONE) {
19,435✔
695
        AFPWritePacket(p, TPACKET_V2);
19,133✔
696
    }
19,133✔
697

698
    BUG_ON(p->afp_v.relptr == NULL);
19,435✔
699

700
    union thdr h;
19,435✔
701
    h.raw = p->afp_v.relptr;
19,435✔
702
    h.h2->tp_status = TP_STATUS_KERNEL;
19,435✔
703

704
    (void)AFPDerefSocket(p->afp_v.mpeer);
19,435✔
705

706
    AFPV_CLEANUP(&p->afp_v);
19,435✔
707
}
19,435✔
708

709
static void AFPReleasePacketV3(Packet *p)
710
{
100✔
711
    DEBUG_VALIDATE_BUG_ON(PKT_IS_PSEUDOPKT(p));
100✔
712

713
    /* Need to be in copy mode and need to detect early release
714
       where Ethernet header could not be set (and pseudo packet) */
715
    if (p->afp_v.copy_mode != AFP_COPY_MODE_NONE) {
100✔
716
        AFPWritePacket(p, TPACKET_V3);
×
717
    }
×
718
    PacketFreeOrRelease(p);
100✔
719
}
100✔
720

721
static void AFPReleasePacket(Packet *p)
722
{
19,435✔
723
    AFPReleaseDataFromRing(p);
19,435✔
724
    PacketFreeOrRelease(p);
19,435✔
725
}
19,435✔
726

727
/** \internal
728
 *  \brief recoverable error - release packet and
729
 *         return AFP_SURI_FAILURE
730
 */
731
static inline int AFPSuriFailure(AFPThreadVars *ptv, union thdr h)
732
{
×
733
    h.h2->tp_status = TP_STATUS_KERNEL;
×
734
    if (++ptv->frame_offset >= ptv->req.v2.tp_frame_nr) {
×
735
        ptv->frame_offset = 0;
×
736
    }
×
737
    SCReturnInt(AFP_SURI_FAILURE);
×
738
}
×
739

740
static inline void AFPReadApplyBypass(const AFPThreadVars *ptv, Packet *p)
741
{
19,535✔
742
#ifdef HAVE_PACKET_EBPF
743
    if (ptv->flags & AFP_BYPASS) {
744
        p->BypassPacketsFlow = AFPBypassCallback;
745
        p->afp_v.v4_map_fd = ptv->v4_map_fd;
746
        p->afp_v.v6_map_fd = ptv->v6_map_fd;
747
        p->afp_v.nr_cpus = ptv->ebpf_t_config.cpus_count;
748
    }
749
    if (ptv->flags & AFP_XDPBYPASS) {
750
        p->BypassPacketsFlow = AFPXDPBypassCallback;
751
        p->afp_v.v4_map_fd = ptv->v4_map_fd;
752
        p->afp_v.v6_map_fd = ptv->v6_map_fd;
753
        p->afp_v.nr_cpus = ptv->ebpf_t_config.cpus_count;
754
    }
755
#endif
756
}
19,535✔
757

758
/** \internal
759
 *  \brief setup packet for AFPReadFromRing
760
 */
761
static void AFPReadFromRingSetupPacket(
762
        AFPThreadVars *ptv, union thdr h, const unsigned int tp_status, Packet *p)
763
{
19,435✔
764
    PKT_SET_SRC(p, PKT_SRC_WIRE);
19,435✔
765

766
    /* flag the packet as TP_STATUS_USER_BUSY, which is ignore by the kernel, but
767
     * acts as an indicator that we've reached a frame that is not yet released by
768
     * us in autofp mode. It will be cleared when the frame gets released to the kernel. */
769
    h.h2->tp_status |= TP_STATUS_USER_BUSY;
19,435✔
770
    p->livedev = ptv->livedev;
19,435✔
771
    p->datalink = ptv->datalink;
19,435✔
772
    ptv->pkts++;
19,435✔
773

774
    AFPReadApplyBypass(ptv, p);
19,435✔
775

776
    if (h.h2->tp_len > h.h2->tp_snaplen) {
19,435✔
777
        SCLogDebug("Packet length (%d) > snaplen (%d), truncating", h.h2->tp_len, h.h2->tp_snaplen);
×
778
        ENGINE_SET_INVALID_EVENT(p, AFP_TRUNC_PKT);
×
779
    }
×
780

781
    /* get vlan id from header */
782
    if ((ptv->flags & AFP_VLAN_IN_HEADER) &&
19,435✔
783
            (tp_status & TP_STATUS_VLAN_VALID || h.h2->tp_vlan_tci)) {
19,435✔
784
        p->vlan_id[0] = h.h2->tp_vlan_tci & 0x0fff;
×
785
        p->vlan_idx = 1;
×
786
        p->afp_v.vlan_tci = h.h2->tp_vlan_tci;
×
787
    }
×
788

789
    (void)PacketSetData(p, (unsigned char *)h.raw + h.h2->tp_mac, h.h2->tp_snaplen);
19,435✔
790

791
    p->ReleasePacket = AFPReleasePacket;
19,435✔
792
    p->afp_v.relptr = h.raw;
19,435✔
793
    if (ptv->flags & AFP_NEED_PEER) {
19,435✔
794
        p->afp_v.mpeer = ptv->mpeer;
279✔
795
        AFPRefSocket(ptv->mpeer);
279✔
796
    } else {
19,256✔
797
        p->afp_v.mpeer = NULL;
19,156✔
798
    }
19,156✔
799
    p->afp_v.copy_mode = ptv->copy_mode;
19,435✔
800
    p->afp_v.peer = (p->afp_v.copy_mode == AFP_COPY_MODE_NONE) ? NULL : ptv->mpeer->peer;
19,435✔
801

802
    /* Timestamp */
803
    p->ts = (SCTime_t){ .secs = h.h2->tp_sec, .usecs = h.h2->tp_nsec / 1000 };
19,435✔
804
    SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)", GET_PKT_LEN(p), p, GET_PKT_DATA(p));
19,435✔
805

806
    /* We only check for checksum disable */
807
    if (ptv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) {
19,435✔
808
        p->flags |= PKT_IGNORE_CHECKSUM;
×
809
    } else if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) {
19,435✔
810
        if (ChecksumAutoModeCheck(ptv->pkts, SC_ATOMIC_GET(ptv->livedev->pkts),
×
811
                    SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
×
812
            ptv->checksum_mode = CHECKSUM_VALIDATION_DISABLE;
×
813
            p->flags |= PKT_IGNORE_CHECKSUM;
×
814
        }
×
815
    } else {
19,435✔
816
        if (tp_status & TP_STATUS_CSUMNOTREADY) {
19,435✔
817
            p->flags |= PKT_IGNORE_CHECKSUM;
×
818
        }
×
819
    }
19,435✔
820
}
19,435✔
821

822
static inline int AFPReadFromRingWaitForPacket(AFPThreadVars *ptv)
823
{
9,284✔
824
    union thdr h;
9,284✔
825
    struct timeval start_time;
9,284✔
826
    gettimeofday(&start_time, NULL);
9,284✔
827
    int64_t busy_loop_iter = 0;
9,284✔
828

829
    /* busy wait loop until we have packets available */
830
    while (1) {
9,285✔
831
        if (unlikely(suricata_ctl_flags != 0)) {
9,285✔
832
            break;
×
833
        }
×
834
        h.raw = (((union thdr **)ptv->ring.v2)[ptv->frame_offset]);
9,285✔
835
        if (unlikely(h.raw == NULL)) {
9,285✔
836
            return AFP_READ_FAILURE;
×
837
        }
×
838
        const unsigned int tp_status = h.h2->tp_status;
9,285✔
839
        if (tp_status == TP_STATUS_KERNEL) {
9,285✔
840
            busy_loop_iter++;
8,765✔
841

842
            struct timeval cur_time;
8,765✔
843
            memset(&cur_time, 0, sizeof(cur_time));
8,765✔
844
            uint64_t milliseconds =
8,765✔
845
                    ((cur_time.tv_sec - start_time.tv_sec) * 1000) +
8,765✔
846
                    (((1000000 + cur_time.tv_usec - start_time.tv_usec) / 1000) - 1000);
8,765✔
847
            if (milliseconds > 1000) {
8,765✔
848
                break;
8,765✔
849
            }
8,765✔
850
            continue;
×
851
        }
8,765✔
852
        break;
520✔
853
    }
9,285✔
854
    if (busy_loop_iter) {
9,284✔
855
        StatsCounterAvgAddI64(&ptv->tv->stats, ptv->afpacket_spin, busy_loop_iter);
8,765✔
856
    }
8,765✔
857
    return AFP_READ_OK;
9,284✔
858
}
9,284✔
859

860
/**
861
 * \brief AF packet frame ignore logic
862
 *
863
 * Given a sockaddr_ll of a frame, use the pkttype_filter_mask to decide if the
864
 * frame should be ignored. Protect from undefined behavior if there's ever
865
 * a sll_pkttype that would shift by too much. At this point, only outgoing
866
 * packets (4) are ignored. The highest value in if_linux.h is PACKET_KERNEL (7),
867
 * this extra check is being overly cautious.
868
 *
869
 * \retval true if the frame should be ignored
870
 */
871
static inline bool AFPShouldIgnoreFrame(AFPThreadVars *ptv, const struct sockaddr_ll *sll)
872
{
19,535✔
873
    if (unlikely(sll->sll_pkttype > 31))
19,535✔
874
        return false;
×
875

876
    return (ptv->pkttype_filter_mask & BIT_U32(sll->sll_pkttype)) != 0;
19,535✔
877
}
19,535✔
878

879
/**
880
 * \brief AF packet read function for ring
881
 *
882
 * This function fills
883
 * From here the packets are picked up by the DecodeAFP thread.
884
 *
885
 * \param user pointer to AFPThreadVars
886
 * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
887
 */
888
static int AFPReadFromRing(AFPThreadVars *ptv)
889
{
9,285✔
890
    union thdr h;
9,285✔
891
    bool emergency_flush = false;
9,285✔
892
    const unsigned int start_pos = ptv->frame_offset;
9,285✔
893

894
    /* poll() told us there are frames, so lets wait for at least
895
     * one frame to become available. */
896
    if (AFPReadFromRingWaitForPacket(ptv) != AFP_READ_OK)
9,285✔
897
        return AFP_READ_FAILURE;
×
898

899
    /* process the frames in the ring */
900
    while (1) {
28,720✔
901
        if (unlikely(suricata_ctl_flags != 0)) {
28,719✔
902
            break;
×
903
        }
×
904
        h.raw = (((union thdr **)ptv->ring.v2)[ptv->frame_offset]);
28,719✔
905
        if (unlikely(h.raw == NULL)) {
28,719✔
906
            return AFP_READ_FAILURE;
×
907
        }
×
908
        const unsigned int tp_status = h.h2->tp_status;
28,719✔
909
        /* if we find a kernel frame we are done */
910
        if (unlikely(tp_status == TP_STATUS_KERNEL)) {
28,719✔
911
            break;
9,285✔
912
        }
9,285✔
913
        /* if in autofp mode the frame is still busy, return to poll */
914
        if (unlikely(FRAME_BUSY(tp_status))) {
19,434✔
915
            break;
×
916
        }
×
917
        emergency_flush |= ((tp_status & TP_STATUS_LOSING) != 0);
19,434✔
918

919
        if ((ptv->flags & AFP_EMERGENCY_MODE) && emergency_flush) {
19,434✔
920
            h.h2->tp_status = TP_STATUS_KERNEL;
×
921
            goto next_frame;
×
922
        }
×
923

924
        const struct sockaddr_ll *sll =
19,434✔
925
                (const struct sockaddr_ll *)((uint8_t *)h.h2 +
19,434✔
926
                                             TPACKET_ALIGN(sizeof(struct tpacket2_hdr)));
19,434✔
927
        if (unlikely(AFPShouldIgnoreFrame(ptv, sll)))
19,434✔
928
            goto next_frame;
×
929

930
        Packet *p = PacketGetFromQueueOrAlloc();
19,434✔
931
        if (p == NULL) {
19,434✔
932
            return AFPSuriFailure(ptv, h);
×
933
        }
×
934
        AFPReadFromRingSetupPacket(ptv, h, tp_status, p);
19,434✔
935

936
        if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
19,434✔
937
            return AFPSuriFailure(ptv, h);
×
938
        }
×
939
next_frame:
19,435✔
940
        if (++ptv->frame_offset >= ptv->req.v2.tp_frame_nr) {
19,435✔
941
            ptv->frame_offset = 0;
18✔
942
            /* Get out of loop to be sure we will reach maintenance tasks */
943
            if (ptv->frame_offset == start_pos)
18✔
944
                break;
×
945
        }
18✔
946
    }
19,435✔
947
    if (emergency_flush) {
9,286✔
948
        AFPDumpCounters(ptv);
×
949
    }
×
950
    SCReturnInt(AFP_READ_OK);
9,286✔
951
}
9,285✔
952

953
static inline void AFPFlushBlock(struct tpacket_block_desc *pbd)
954
{
50✔
955
    pbd->hdr.bh1.block_status = TP_STATUS_KERNEL;
50✔
956
}
50✔
957

958
static inline int AFPParsePacketV3(AFPThreadVars *ptv, struct tpacket_block_desc *pbd, struct tpacket3_hdr *ppd)
959
{
100✔
960
    Packet *p = PacketGetFromQueueOrAlloc();
100✔
961
    if (p == NULL) {
100✔
962
        SCReturnInt(AFP_SURI_FAILURE);
×
963
    }
×
964
    PKT_SET_SRC(p, PKT_SRC_WIRE);
100✔
965

966
    AFPReadApplyBypass(ptv, p);
100✔
967

968
    ptv->pkts++;
100✔
969
    p->livedev = ptv->livedev;
100✔
970
    p->datalink = ptv->datalink;
100✔
971

972
    if ((ptv->flags & AFP_VLAN_IN_HEADER) &&
100✔
973
            (ppd->tp_status & TP_STATUS_VLAN_VALID || ppd->hv1.tp_vlan_tci)) {
100✔
974
        p->vlan_id[0] = ppd->hv1.tp_vlan_tci & 0x0fff;
×
975
        p->vlan_idx = 1;
×
976
        p->afp_v.vlan_tci = (uint16_t)ppd->hv1.tp_vlan_tci;
×
977
    }
×
978

979
    if (ppd->tp_len > ppd->tp_snaplen) {
100✔
980
        SCLogDebug("Packet length (%d) > snaplen (%d), truncating", ppd->tp_len, ppd->tp_snaplen);
×
981
        ENGINE_SET_INVALID_EVENT(p, AFP_TRUNC_PKT);
×
982
    }
×
983

984
    (void)PacketSetData(p, (unsigned char *)ppd + ppd->tp_mac, ppd->tp_snaplen);
100✔
985

986
    p->ReleasePacket = AFPReleasePacketV3;
100✔
987
    p->afp_v.relptr = NULL;
100✔
988
    p->afp_v.mpeer = NULL;
100✔
989
    p->afp_v.copy_mode = ptv->copy_mode;
100✔
990
    p->afp_v.peer = (p->afp_v.copy_mode == AFP_COPY_MODE_NONE) ? NULL : ptv->mpeer->peer;
100✔
991

992
    /* Timestamp */
993
    p->ts = (SCTime_t){ .secs = ppd->tp_sec, .usecs = ppd->tp_nsec / 1000 };
100✔
994
    SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)",
100✔
995
            GET_PKT_LEN(p), p, GET_PKT_DATA(p));
100✔
996

997
    /* We only check for checksum disable */
998
    if (ptv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) {
100✔
999
        p->flags |= PKT_IGNORE_CHECKSUM;
×
1000
    } else if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) {
100✔
1001
        if (ChecksumAutoModeCheck(ptv->pkts,
×
1002
                    SC_ATOMIC_GET(ptv->livedev->pkts),
×
1003
                    SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
×
1004
            ptv->checksum_mode = CHECKSUM_VALIDATION_DISABLE;
×
1005
            p->flags |= PKT_IGNORE_CHECKSUM;
×
1006
        }
×
1007
    } else {
100✔
1008
        if (ppd->tp_status & TP_STATUS_CSUMNOTREADY) {
100✔
1009
            p->flags |= PKT_IGNORE_CHECKSUM;
×
1010
        }
×
1011
    }
100✔
1012

1013
    if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
100✔
1014
        SCReturnInt(AFP_SURI_FAILURE);
×
1015
    }
×
1016

1017
    SCReturnInt(AFP_READ_OK);
100✔
1018
}
100✔
1019

1020
static inline int AFPWalkBlock(AFPThreadVars *ptv, struct tpacket_block_desc *pbd)
1021
{
50✔
1022
    const int num_pkts = pbd->hdr.bh1.num_pkts;
50✔
1023
    uint8_t *ppd = (uint8_t *)pbd + pbd->hdr.bh1.offset_to_first_pkt;
50✔
1024

1025
    for (int i = 0; i < num_pkts; ++i) {
150✔
1026
        const struct sockaddr_ll *sll =
100✔
1027
                (const struct sockaddr_ll *)(ppd + TPACKET_ALIGN(sizeof(struct tpacket3_hdr)));
100✔
1028
        if (unlikely(AFPShouldIgnoreFrame(ptv, sll))) {
100✔
1029
            ppd = ppd + ((struct tpacket3_hdr *)ppd)->tp_next_offset;
×
1030
            continue;
×
1031
        }
×
1032
        int ret = AFPParsePacketV3(ptv, pbd, (struct tpacket3_hdr *)ppd);
100✔
1033
        switch (ret) {
100✔
1034
            case AFP_READ_OK:
100✔
1035
                break;
100✔
1036
            case AFP_SURI_FAILURE:
×
1037
                /* Internal error but let's just continue and
1038
                 * treat thenext packet */
1039
                break;
×
1040
            case AFP_READ_FAILURE:
×
1041
                SCReturnInt(AFP_READ_FAILURE);
×
1042
            default:
×
1043
                SCReturnInt(ret);
×
1044
        }
100✔
1045
        ppd = ppd + ((struct tpacket3_hdr *)ppd)->tp_next_offset;
100✔
1046
    }
100✔
1047

1048
    SCReturnInt(AFP_READ_OK);
50✔
1049
}
50✔
1050

1051
/**
1052
 * \brief AF packet read function for ring
1053
 *
1054
 * This function fills
1055
 * From here the packets are picked up by the DecodeAFP thread.
1056
 *
1057
 * \param user pointer to AFPThreadVars
1058
 * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
1059
 */
1060
static int AFPReadFromRingV3(AFPThreadVars *ptv)
1061
{
50✔
1062
    /* Loop till we have packets available */
1063
    while (1) {
93✔
1064
        if (unlikely(suricata_ctl_flags != 0)) {
93✔
1065
            SCLogDebug("Exiting AFP V3 read loop");
×
1066
            break;
×
1067
        }
×
1068

1069
        struct tpacket_block_desc *pbd =
93✔
1070
                (struct tpacket_block_desc *)ptv->ring.v3[ptv->frame_offset].iov_base;
93✔
1071

1072
        /* block is not ready to be read */
1073
        if ((pbd->hdr.bh1.block_status & TP_STATUS_USER) == 0) {
93✔
1074
            SCReturnInt(AFP_READ_OK);
43✔
1075
        }
43✔
1076

1077
        int ret = AFPWalkBlock(ptv, pbd);
50✔
1078
        if (unlikely(ret != AFP_READ_OK)) {
50✔
1079
            AFPFlushBlock(pbd);
×
1080
            SCReturnInt(ret);
×
1081
        }
×
1082

1083
        AFPFlushBlock(pbd);
50✔
1084
        ptv->frame_offset = (ptv->frame_offset + 1) % ptv->req.v3.tp_block_nr;
50✔
1085
        /* return to maintenance task after one loop on the ring */
1086
        if (ptv->frame_offset == 0) {
50✔
1087
            SCReturnInt(AFP_READ_OK);
7✔
1088
        }
7✔
1089
    }
50✔
1090
    SCReturnInt(AFP_READ_OK);
50✔
1091
}
50✔
1092

1093
/**
1094
 * \brief Reference socket
1095
 *
1096
 * \retval O in case of failure, 1 in case of success
1097
 */
1098
static int AFPRefSocket(AFPPeer* peer)
1099
{
279✔
1100
    if (unlikely(peer == NULL))
279✔
1101
        return 0;
×
1102

1103
    (void)SC_ATOMIC_ADD(peer->sock_usage, 1);
279✔
1104
    return 1;
279✔
1105
}
279✔
1106

1107

1108
/**
1109
 * \brief Dereference socket
1110
 *
1111
 * \retval 1 if socket is still alive, 0 if not
1112
 */
1113
static int AFPDerefSocket(AFPPeer* peer)
1114
{
19,435✔
1115
    if (peer == NULL)
19,435✔
1116
        return 1;
19,156✔
1117

1118
    if (SC_ATOMIC_SUB(peer->sock_usage, 1) == 1) {
279✔
1119
        return 0;
×
1120
    }
×
1121
    return 1;
279✔
1122
}
279✔
1123

1124
static void AFPCloseSocket(AFPThreadVars *ptv)
1125
{
×
1126
    if (ptv->mpeer != NULL)
×
1127
        BUG_ON(SC_ATOMIC_GET(ptv->mpeer->sock_usage) != 0);
×
1128

1129
    if (ptv->flags & AFP_TPACKET_V3) {
×
1130
        if (ptv->ring.v3) {
×
1131
            SCFree(ptv->ring.v3);
×
1132
            ptv->ring.v3 = NULL;
×
1133
        }
×
1134
    } else {
×
1135
        if (ptv->ring.v2) {
×
1136
            /* only used in reading phase, we can free it */
1137
            SCFree(ptv->ring.v2);
×
1138
            ptv->ring.v2 = NULL;
×
1139
        }
×
1140
    }
×
1141
    if (ptv->socket != -1) {
×
1142
        SCLogDebug("Cleaning socket connected to '%s'", ptv->iface);
×
1143
        munmap(ptv->ring_buf, ptv->ring_buflen);
×
1144
        close(ptv->socket);
×
1145
        ptv->socket = -1;
×
1146
    }
×
1147
}
×
1148

1149
static void AFPSwitchState(AFPThreadVars *ptv, uint8_t state)
1150
{
80✔
1151
    ptv->afp_state = state;
80✔
1152
    ptv->down_count = 0;
80✔
1153

1154
    if (state == AFP_STATE_DOWN) {
80✔
1155
        /* cleanup is done on thread cleanup or try reopen
1156
         * as there may still be packets in autofp that
1157
         * are referencing us */
1158
        (void)SC_ATOMIC_SUB(ptv->mpeer->sock_usage, 1);
40✔
1159
    }
40✔
1160
    if (state == AFP_STATE_UP) {
80✔
1161
        AFPPeerUpdate(ptv);
40✔
1162
        (void)SC_ATOMIC_SET(ptv->mpeer->sock_usage, 1);
40✔
1163
    }
40✔
1164
}
80✔
1165

1166
static int AFPReadAndDiscardFromRing(AFPThreadVars *ptv, struct timeval *synctv,
1167
                                     uint64_t *discarded_pkts)
1168
{
2✔
1169
    if (unlikely(suricata_ctl_flags != 0)) {
2✔
1170
        return 1;
×
1171
    }
×
1172

1173
    if (ptv->flags & AFP_TPACKET_V3) {
2✔
1174
        int ret = 0;
×
1175
        struct tpacket_block_desc *pbd =
×
1176
                (struct tpacket_block_desc *)ptv->ring.v3[ptv->frame_offset].iov_base;
×
1177
        *discarded_pkts += pbd->hdr.bh1.num_pkts;
×
1178
        struct tpacket3_hdr *ppd =
×
1179
            (struct tpacket3_hdr *)((uint8_t *)pbd + pbd->hdr.bh1.offset_to_first_pkt);
×
1180
        if (((time_t)ppd->tp_sec > synctv->tv_sec) ||
×
1181
                ((time_t)ppd->tp_sec == synctv->tv_sec &&
×
1182
                 (suseconds_t) (ppd->tp_nsec / 1000) > (suseconds_t)synctv->tv_usec)) {
×
1183
            ret = 1;
×
1184
        }
×
1185
        AFPFlushBlock(pbd);
×
1186
        ptv->frame_offset = (ptv->frame_offset + 1) % ptv->req.v3.tp_block_nr;
×
1187
        return ret;
×
1188

1189
    } else {
2✔
1190
        /* Read packet from ring */
1191
        union thdr h;
2✔
1192
        h.raw = (((union thdr **)ptv->ring.v2)[ptv->frame_offset]);
2✔
1193
        if (h.raw == NULL) {
2✔
1194
            return -1;
×
1195
        }
×
1196
        if (h.h2->tp_status == TP_STATUS_KERNEL)
2✔
1197
            return 0;
×
1198

1199
        if (((time_t)h.h2->tp_sec > synctv->tv_sec) ||
2✔
1200
                ((time_t)h.h2->tp_sec == synctv->tv_sec &&
2✔
1201
                 (suseconds_t) (h.h2->tp_nsec / 1000) > synctv->tv_usec)) {
2✔
1202
            return 1;
×
1203
        }
×
1204

1205
        (*discarded_pkts)++;
2✔
1206
        h.h2->tp_status = TP_STATUS_KERNEL;
2✔
1207
        if (++ptv->frame_offset >= ptv->req.v2.tp_frame_nr) {
2✔
1208
            ptv->frame_offset = 0;
×
1209
        }
×
1210
    }
2✔
1211

1212
    return 0;
2✔
1213
}
2✔
1214

1215
/** \brief wait for all afpacket threads to fully init
1216
 *
1217
 *  Discard packets before all threads are ready, as the cluster
1218
 *  setup is not complete yet.
1219
 *
1220
 *  if AFPPeersListStarted() returns true init is complete
1221
 *
1222
 *  \retval r 1 = happy, otherwise unhappy
1223
 */
1224
static int AFPSynchronizeStart(AFPThreadVars *ptv, uint64_t *discarded_pkts)
1225
{
40✔
1226
    struct timeval synctv;
40✔
1227
    struct pollfd fds;
40✔
1228

1229
    fds.fd = ptv->socket;
40✔
1230
    fds.events = POLLIN;
40✔
1231

1232
    /* Set timeval to end of the world */
1233
    synctv.tv_sec = 0xffffffff;
40✔
1234
    synctv.tv_usec = 0xffffffff;
40✔
1235

1236
    while (1) {
42✔
1237
        int r = poll(&fds, 1, POLL_TIMEOUT);
42✔
1238
        if (r > 0 &&
42✔
1239
                (fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) {
42✔
1240
            SCLogWarning("%s: poll failed %02x", ptv->iface,
×
1241
                    fds.revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL));
×
1242
            return 0;
×
1243
        } else if (r > 0) {
42✔
1244
            if (AFPPeersListStarted() && synctv.tv_sec == (time_t) 0xffffffff) {
2✔
1245
                gettimeofday(&synctv, NULL);
2✔
1246
            }
2✔
1247
            r = AFPReadAndDiscardFromRing(ptv, &synctv, discarded_pkts);
2✔
1248
            SCLogDebug("Discarding on %s", ptv->tv->name);
2✔
1249
            switch (r) {
2✔
1250
                case 1:
×
1251
                    SCLogDebug("Starting to read on %s", ptv->tv->name);
×
1252
                    return 1;
×
1253
                case -1:
×
1254
                    return r;
×
1255
            }
2✔
1256
        /* no packets */
1257
        } else if (r == 0 && AFPPeersListStarted()) {
40✔
1258
            SCLogDebug("Starting to read on %s", ptv->tv->name);
40✔
1259
            return 1;
40✔
1260
        } else if (r < 0) { /* only exit on error */
40✔
1261
            SCLogWarning("poll failed with retval %d", r);
×
1262
            return 0;
×
1263
        }
×
1264
    }
42✔
1265
    return 1;
×
1266
}
40✔
1267

1268
/**
1269
 * \brief Try to reopen socket
1270
 *
1271
 * \retval 0 in case of success, negative if error occurs or a condition
1272
 * is not met.
1273
 */
1274
static int AFPTryReopen(AFPThreadVars *ptv)
1275
{
×
1276
    ptv->down_count++;
×
1277

1278
    /* Don't reconnect till we have packet that did not release data */
1279
    if (SC_ATOMIC_GET(ptv->mpeer->sock_usage) != 0) {
×
1280
        return -1;
×
1281
    }
×
1282

1283
    /* ref cnt 0, we can close the old socket */
1284
    AFPCloseSocket(ptv);
×
1285

1286
    int afp_activate_r = AFPCreateSocket(ptv, ptv->iface, 0, false);
×
1287
    if (afp_activate_r != 0) {
×
1288
        if (ptv->down_count % AFP_DOWN_COUNTER_INTERVAL == 0) {
×
1289
            SCLogWarning("%s: can't reopen interface", ptv->iface);
×
1290
        }
×
1291
        return afp_activate_r;
×
1292
    }
×
1293

1294
    SCLogInfo("%s: interface is back up", ptv->iface);
×
1295
    return 0;
×
1296
}
×
1297

1298
/**
1299
 *  \brief Main AF_PACKET reading Loop function
1300
 */
1301
TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot)
1302
{
40✔
1303
    SCEnter();
40✔
1304

1305
    AFPThreadVars *ptv = (AFPThreadVars *)data;
40✔
1306
    struct pollfd fds;
40✔
1307
    int r;
40✔
1308
    TmSlot *s = (TmSlot *)slot;
40✔
1309
    time_t last_dump = 0;
40✔
1310
    time_t current_time;
40✔
1311
    int (*AFPReadFunc) (AFPThreadVars *);
40✔
1312
    uint64_t discarded_pkts = 0;
40✔
1313

1314
    ptv->slot = s->slot_next;
40✔
1315

1316
    if (ptv->flags & AFP_TPACKET_V3) {
40✔
1317
        AFPReadFunc = AFPReadFromRingV3;
4✔
1318
    } else {
36✔
1319
        AFPReadFunc = AFPReadFromRing;
36✔
1320
    }
36✔
1321

1322
    if (ptv->afp_state == AFP_STATE_DOWN) {
40✔
1323
        /* Wait for our turn, threads before us must have opened the socket */
1324
        while (AFPPeersListWaitTurn(ptv->mpeer)) {
925✔
1325
            usleep(1000);
885✔
1326
            if (suricata_ctl_flags != 0) {
885✔
1327
                break;
×
1328
            }
×
1329
        }
885✔
1330
        r = AFPCreateSocket(ptv, ptv->iface, 1, true);
40✔
1331
        if (r < 0) {
40✔
1332
            switch (-r) {
×
1333
                case AFP_FATAL_ERROR:
×
1334
                    SCLogError("%s: failed to init socket for interface", ptv->iface);
×
1335
                    SCReturnInt(TM_ECODE_FAILED);
×
1336
                case AFP_RECOVERABLE_ERROR:
×
1337
                    SCLogWarning(
×
1338
                            "%s: failed to init socket for interface, retrying soon", ptv->iface);
×
1339
            }
×
1340
        }
×
1341
    }
40✔
1342
    if (ptv->afp_state == AFP_STATE_UP) {
40✔
1343
        SCLogDebug("Thread %s using socket %d", tv->name, ptv->socket);
40✔
1344
        AFPSynchronizeStart(ptv, &discarded_pkts);
40✔
1345
        /* let's reset counter as we will start the capture at the
1346
         * next function call */
1347
#ifdef PACKET_STATISTICS
40✔
1348
         struct tpacket_stats kstats;
40✔
1349
         socklen_t len = sizeof (struct tpacket_stats);
40✔
1350
         if (getsockopt(ptv->socket, SOL_PACKET, PACKET_STATISTICS,
40✔
1351
                     &kstats, &len) > -1) {
40✔
1352
             int64_t pkts = 0;
40✔
1353
             SCLogDebug("(%s) Kernel socket startup: Packets %" PRIu32
40✔
1354
                     ", dropped %" PRIu32 "",
40✔
1355
                     ptv->tv->name,
40✔
1356
                     kstats.tp_packets, kstats.tp_drops);
40✔
1357
             pkts = kstats.tp_packets - discarded_pkts - kstats.tp_drops;
40✔
1358
             StatsCounterAddI64(&ptv->tv->stats, ptv->capture_kernel_packets, pkts);
40✔
1359
             (void) SC_ATOMIC_ADD(ptv->livedev->pkts, pkts);
40✔
1360
         }
40✔
1361
#endif
40✔
1362
    }
40✔
1363

1364
    fds.fd = ptv->socket;
40✔
1365
    fds.events = POLLIN;
40✔
1366

1367
    // Indicate that the thread is actually running its application level code (i.e., it can poll
1368
    // packets)
1369
    TmThreadsSetFlag(tv, THV_RUNNING);
40✔
1370

1371
    while (1) {
32,252✔
1372
        /* Start by checking the state of our interface */
1373
        if (unlikely(ptv->afp_state == AFP_STATE_DOWN)) {
32,252✔
1374
            int dbreak = 0;
×
1375

1376
            do {
×
1377
                usleep(AFP_RECONNECT_TIMEOUT);
×
1378
                if (suricata_ctl_flags != 0) {
×
1379
                    dbreak = 1;
×
1380
                    break;
×
1381
                }
×
1382
                r = AFPTryReopen(ptv);
×
1383
                fds.fd = ptv->socket;
×
1384
            } while (r < 0);
×
1385
            if (dbreak == 1)
×
1386
                break;
×
1387
        }
×
1388

1389
        /* make sure we have at least one packet in the packet pool, to prevent
1390
         * us from alloc'ing packets at line rate */
1391
        PacketPoolWait();
32,252✔
1392

1393
        StatsCounterIncr(&ptv->tv->stats, ptv->capture_afp_poll);
32,252✔
1394

1395
        r = poll(&fds, 1, POLL_TIMEOUT);
32,252✔
1396

1397
        if (suricata_ctl_flags != 0) {
32,252✔
1398
            break;
40✔
1399
        }
40✔
1400

1401
        if (r > 0 &&
32,212✔
1402
                (fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) {
32,212✔
1403
            StatsCounterIncr(&ptv->tv->stats, ptv->capture_afp_poll_signal);
×
1404
            if (fds.revents & (POLLHUP | POLLRDHUP)) {
×
1405
                AFPSwitchState(ptv, AFP_STATE_DOWN);
×
1406
                continue;
×
1407
            } else if (fds.revents & POLLERR) {
×
1408
                char c;
×
1409
                /* Do a recv to get errno */
1410
                if (recv(ptv->socket, &c, sizeof c, MSG_PEEK) != -1)
×
1411
                    continue; /* what, no error? */
×
1412
                SCLogWarning("%s: failed to poll interface: %s", ptv->iface, strerror(errno));
×
1413
                AFPSwitchState(ptv, AFP_STATE_DOWN);
×
1414
                continue;
×
1415
            } else if (fds.revents & POLLNVAL) {
×
1416
                SCLogWarning("%s: invalid poll request: %s", ptv->iface, strerror(errno));
×
1417
                AFPSwitchState(ptv, AFP_STATE_DOWN);
×
1418
                continue;
×
1419
            }
×
1420
        } else if (r > 0) {
32,212✔
1421
            StatsCounterIncr(&ptv->tv->stats, ptv->capture_afp_poll_data);
9,335✔
1422
            r = AFPReadFunc(ptv);
9,335✔
1423
            switch (r) {
9,335✔
1424
                case AFP_READ_OK:
9,335✔
1425
                    /* Trigger one dump of stats every second */
1426
                    current_time = time(NULL);
9,335✔
1427
                    if (current_time != last_dump) {
9,335✔
1428
                        AFPDumpCounters(ptv);
14✔
1429
                        last_dump = current_time;
14✔
1430
                    }
14✔
1431
                    break;
9,335✔
1432
                case AFP_READ_FAILURE:
×
1433
                    /* AFPRead in error: best to reset the socket */
1434
                    SCLogWarning("%s: read failure: %s", ptv->iface, strerror(errno));
×
1435
                    AFPSwitchState(ptv, AFP_STATE_DOWN);
×
1436
                    continue;
×
1437
                case AFP_SURI_FAILURE:
×
1438
                    StatsCounterIncr(&ptv->tv->stats, ptv->capture_errors);
×
1439
                    break;
×
1440
                case AFP_KERNEL_DROP:
×
1441
                    AFPDumpCounters(ptv);
×
1442
                    break;
×
1443
            }
9,335✔
1444
        } else if (unlikely(r == 0)) {
22,897✔
1445
            StatsCounterIncr(&ptv->tv->stats, ptv->capture_afp_poll_timeout);
22,897✔
1446
            /* Trigger one dump of stats every second */
1447
            current_time = time(NULL);
22,897✔
1448
            if (current_time != last_dump) {
22,897✔
1449
                AFPDumpCounters(ptv);
2,337✔
1450
                last_dump = current_time;
2,337✔
1451
            }
2,337✔
1452
            /* poll timed out, lets see handle our timeout path */
1453
            TmThreadsCaptureHandleTimeout(tv, NULL);
22,897✔
1454

1455
        } else if ((r < 0) && (errno != EINTR)) {
2,147,491,449✔
1456
            StatsCounterIncr(&ptv->tv->stats, ptv->capture_afp_poll_err);
×
1457
            SCLogWarning("%s: poll failure: %s", ptv->iface, strerror(errno));
×
1458
            AFPSwitchState(ptv, AFP_STATE_DOWN);
×
1459
            continue;
×
1460
        }
×
1461
        StatsSyncCountersIfSignalled(&tv->stats);
32,212✔
1462
    }
32,212✔
1463

1464
    AFPDumpCounters(ptv);
40✔
1465
    StatsSyncCountersIfSignalled(&tv->stats);
40✔
1466
    SCReturnInt(TM_ECODE_OK);
40✔
1467
}
40✔
1468

1469
static int AFPGetDevFlags(int fd, const char *ifname)
1470
{
40✔
1471
    struct ifreq ifr;
40✔
1472

1473
    memset(&ifr, 0, sizeof(ifr));
40✔
1474
    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
40✔
1475

1476
    if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
40✔
1477
        SCLogError("%s: failed to get interface flags: %s", ifname, strerror(errno));
×
1478
        return -1;
×
1479
    }
×
1480

1481
    return ifr.ifr_flags;
40✔
1482
}
40✔
1483

1484

1485
static int AFPGetIfnumByDev(int fd, const char *ifname, int verbose)
1486
{
120✔
1487
    struct ifreq ifr;
120✔
1488

1489
    memset(&ifr, 0, sizeof(ifr));
120✔
1490
    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
120✔
1491

1492
    if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) {
120✔
1493
        if (verbose)
40✔
1494
            SCLogError("%s: failed to find interface: %s", ifname, strerror(errno));
×
1495
        return -1;
40✔
1496
    }
40✔
1497

1498
    return ifr.ifr_ifindex;
80✔
1499
}
120✔
1500

1501
static int AFPGetDevLinktype(int fd, const char *ifname)
1502
{
54✔
1503
    struct ifreq ifr;
54✔
1504

1505
    memset(&ifr, 0, sizeof(ifr));
54✔
1506
    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
54✔
1507

1508
    if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
54✔
1509
        SCLogError("%s: failed to find interface type: %s", ifname, strerror(errno));
×
1510
        return -1;
×
1511
    }
×
1512

1513
    switch (ifr.ifr_hwaddr.sa_family) {
54✔
1514
        case ARPHRD_LOOPBACK:
×
1515
            return LINKTYPE_ETHERNET;
×
1516
        case ARPHRD_PPP:
×
1517
        case ARPHRD_NONE:
×
1518
            return LINKTYPE_RAW;
×
1519
        default:
54✔
1520
            return ifr.ifr_hwaddr.sa_family;
54✔
1521
    }
54✔
1522
}
54✔
1523

1524
int AFPGetLinkType(const char *ifname)
1525
{
14✔
1526
    int ltype;
14✔
1527

1528
    int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
14✔
1529
    if (fd == -1) {
14✔
1530
        SCLogError("%s: failed to create AF_PACKET socket: %s", ifname, strerror(errno));
×
1531
        return LINKTYPE_RAW;
×
1532
    }
×
1533

1534
    ltype =  AFPGetDevLinktype(fd, ifname);
14✔
1535
    close(fd);
14✔
1536

1537
    DatalinkSetGlobalType(ltype);
14✔
1538

1539
    return ltype;
14✔
1540
}
14✔
1541

1542
static int AFPComputeRingParams(AFPThreadVars *ptv, int order)
1543
{
36✔
1544
    /* Compute structure:
1545
       Target is to store all pending packets
1546
       with a size equal to MTU + auxdata
1547
       And we keep a decent number of block
1548

1549
       To do so:
1550
       Compute frame_size (aligned to be able to fit in block
1551
       Check which block size we need. Blocksize is a 2^n * pagesize
1552
       We then need to get order, big enough to have
1553
       frame_size < block size
1554
       Find number of frame per block (divide)
1555
       Fill in packet_req
1556

1557
       Compute frame size:
1558
       described in packet_mmap.txt
1559
       dependent on snaplen (need to use a variable ?)
1560
snaplen: MTU ?
1561
tp_hdrlen determine_version in daq_afpacket
1562
in V1:  sizeof(struct tpacket_hdr);
1563
in V2: val in getsockopt(instance->fd, SOL_PACKET, PACKET_HDRLEN, &val, &len)
1564
frame size: TPACKET_ALIGN(snaplen + TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct
1565
sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
1566

1567
     */
1568
    int tp_hdrlen = sizeof(struct tpacket_hdr);
36✔
1569
    int snaplen = default_packet_size;
36✔
1570

1571
    if (snaplen == 0) {
36✔
1572
        if (ptv->cluster_type & PACKET_FANOUT_FLAG_DEFRAG) {
36✔
1573
            SCLogConfig("%s: defrag enabled, setting snaplen to %d", ptv->iface,
12✔
1574
                    DEFAULT_TPACKET_DEFRAG_SNAPLEN);
12✔
1575
            snaplen = DEFAULT_TPACKET_DEFRAG_SNAPLEN;
12✔
1576
        } else {
36✔
1577
            snaplen = GetIfaceMaxPacketSize(ptv->livedev);
24✔
1578
            if (snaplen <= 0) {
24✔
1579
                SCLogWarning("%s: unable to get MTU, setting snaplen default of 1514", ptv->iface);
×
1580
                snaplen = 1514;
×
1581
            }
×
1582
        }
24✔
1583
    }
36✔
1584
    ptv->snaplen = snaplen;
36✔
1585

1586
    ptv->req.v2.tp_frame_size = TPACKET_ALIGN(snaplen +TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
36✔
1587
    ptv->req.v2.tp_block_size = getpagesize() << order;
36✔
1588
    int frames_per_block = ptv->req.v2.tp_block_size / ptv->req.v2.tp_frame_size;
36✔
1589
    if (frames_per_block == 0) {
36✔
1590
        SCLogError("%s: Frame size bigger than block size", ptv->iface);
×
1591
        return -1;
×
1592
    }
×
1593
    ptv->req.v2.tp_frame_nr = ptv->ring_size;
36✔
1594
    ptv->req.v2.tp_block_nr = ptv->req.v2.tp_frame_nr / frames_per_block + 1;
36✔
1595
    /* exact division */
1596
    ptv->req.v2.tp_frame_nr = ptv->req.v2.tp_block_nr * frames_per_block;
36✔
1597
    SCLogPerf("%s: rx ring: block_size=%d block_nr=%d frame_size=%d frame_nr=%d", ptv->iface,
36✔
1598
            ptv->req.v2.tp_block_size, ptv->req.v2.tp_block_nr, ptv->req.v2.tp_frame_size,
36✔
1599
            ptv->req.v2.tp_frame_nr);
36✔
1600
    return 1;
36✔
1601
}
36✔
1602

1603
static int AFPComputeRingParamsWithBlockSize(AFPThreadVars *ptv, unsigned int block_size)
1604
{
×
1605
    /* Compute structure:
1606
       Target is to store all pending packets
1607
       with a size equal to MTU + auxdata
1608
       And we keep a decent number of block
1609

1610
       To do so:
1611
       Compute frame_size (aligned to be able to fit in block
1612
       Check which block size we need. Blocksize is a 2^n * pagesize
1613
       We then need to get order, big enough to have
1614
       frame_size < block size
1615
       Find number of frame per block (divide)
1616
       Fill in packet_req
1617

1618
       Compute frame size:
1619
       described in packet_mmap.txt
1620
       dependent on snaplen (need to use a variable ?)
1621
snaplen: MTU ?
1622
tp_hdrlen determine_version in daq_afpacket
1623
in V1:  sizeof(struct tpacket_hdr);
1624
in V2: val in getsockopt(instance->fd, SOL_PACKET, PACKET_HDRLEN, &val, &len)
1625
frame size: TPACKET_ALIGN(snaplen + TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct
1626
sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
1627

1628
     */
1629
    int tp_hdrlen = sizeof(struct tpacket_hdr);
×
1630
    int snaplen = default_packet_size;
×
1631

1632
    if (snaplen == 0) {
×
1633
        if (ptv->cluster_type & PACKET_FANOUT_FLAG_DEFRAG) {
×
1634
            SCLogConfig("%s: defrag enabled, setting snaplen to %d", ptv->iface,
×
1635
                    DEFAULT_TPACKET_DEFRAG_SNAPLEN);
×
1636
            snaplen = DEFAULT_TPACKET_DEFRAG_SNAPLEN;
×
1637
        } else {
×
1638
            snaplen = GetIfaceMaxPacketSize(ptv->livedev);
×
1639
            if (snaplen <= 0) {
×
1640
                SCLogWarning("%s: unable to get MTU, setting snaplen default of 1514", ptv->iface);
×
1641
                snaplen = 1514;
×
1642
            }
×
1643
        }
×
1644
    }
×
1645
    ptv->snaplen = snaplen;
×
1646

1647
    ptv->req.v2.tp_frame_size = TPACKET_ALIGN(
×
1648
            snaplen +
×
1649
            TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) -
×
1650
            ETH_HLEN);
×
1651
    ptv->req.v2.tp_block_size = block_size;
×
1652
    int frames_per_block = ptv->req.v2.tp_block_size / ptv->req.v2.tp_frame_size;
×
1653
    if (frames_per_block == 0) {
×
1654
        SCLogError("%s: Frame size bigger than block size", ptv->iface);
×
1655
        return -1;
×
1656
    }
×
1657
    ptv->req.v2.tp_frame_nr = ptv->ring_size;
×
1658
    ptv->req.v2.tp_block_nr = ptv->req.v2.tp_frame_nr / frames_per_block + 1;
×
1659
    /* exact division */
1660
    ptv->req.v2.tp_frame_nr = ptv->req.v2.tp_block_nr * frames_per_block;
×
1661
    SCLogPerf("%s: rx ring: block_size=%d block_nr=%d frame_size=%d frame_nr=%d", ptv->iface,
×
1662
            ptv->req.v2.tp_block_size, ptv->req.v2.tp_block_nr, ptv->req.v2.tp_frame_size,
×
1663
            ptv->req.v2.tp_frame_nr);
×
1664
    return 1;
×
1665
}
×
1666

1667
static int AFPComputeRingParamsV3(AFPThreadVars *ptv)
1668
{
4✔
1669
    ptv->req.v3.tp_block_size = ptv->block_size;
4✔
1670
    ptv->req.v3.tp_frame_size = 2048;
4✔
1671
    int frames_per_block = 0;
4✔
1672
    int tp_hdrlen = sizeof(struct tpacket3_hdr);
4✔
1673
    int snaplen = default_packet_size;
4✔
1674

1675
    if (snaplen == 0) {
4✔
1676
        snaplen = GetIfaceMaxPacketSize(ptv->livedev);
4✔
1677
        if (snaplen <= 0) {
4✔
1678
            SCLogWarning("%s: unable to get MTU, setting snaplen default of 1514", ptv->iface);
×
1679
            snaplen = 1514;
×
1680
        }
×
1681
    }
4✔
1682
    ptv->snaplen = snaplen;
4✔
1683

1684
    ptv->req.v3.tp_frame_size = TPACKET_ALIGN(snaplen +TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
4✔
1685
    frames_per_block = ptv->req.v3.tp_block_size / ptv->req.v3.tp_frame_size;
4✔
1686

1687
    if (frames_per_block == 0) {
4✔
1688
        SCLogError("%s: block size is too small, it should be at least %d", ptv->iface,
×
1689
                ptv->req.v3.tp_frame_size);
×
1690
        return -1;
×
1691
    }
×
1692
    ptv->req.v3.tp_block_nr = ptv->ring_size / frames_per_block + 1;
4✔
1693
    /* exact division */
1694
    ptv->req.v3.tp_frame_nr = ptv->req.v3.tp_block_nr * frames_per_block;
4✔
1695
    ptv->req.v3.tp_retire_blk_tov = ptv->block_timeout;
4✔
1696
    ptv->req.v3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
4✔
1697
    SCLogPerf("%s: rx ring params: block_size=%d block_nr=%d frame_size=%d frame_nr=%d (mem: %d)",
4✔
1698
            ptv->iface, ptv->req.v3.tp_block_size, ptv->req.v3.tp_block_nr,
4✔
1699
            ptv->req.v3.tp_frame_size, ptv->req.v3.tp_frame_nr,
4✔
1700
            ptv->req.v3.tp_block_size * ptv->req.v3.tp_block_nr);
4✔
1701
    return 1;
4✔
1702
}
4✔
1703

1704
static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
1705
{
40✔
1706
    int val;
40✔
1707
    unsigned int len = sizeof(val), i;
40✔
1708
    int order;
40✔
1709
    int r, mmap_flag;
40✔
1710

1711
    if (ptv->flags & AFP_TPACKET_V3) {
40✔
1712
        val = TPACKET_V3;
4✔
1713
    } else {
36✔
1714
        val = TPACKET_V2;
36✔
1715
    }
36✔
1716
    if (getsockopt(ptv->socket, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0) {
40✔
1717
        if (errno == ENOPROTOOPT) {
×
1718
            if (ptv->flags & AFP_TPACKET_V3) {
×
1719
                SCLogError("%s: kernel too old for TPACKET_V3 (need 3.2+)", devname);
×
1720
            } else {
×
1721
                SCLogError("%s: kernel too old (need 2.6.27+)", devname);
×
1722
            }
×
1723
        }
×
1724
        SCLogError("%s: failed to retrieve packet header len", devname);
×
1725
        return AFP_FATAL_ERROR;
×
1726
    }
×
1727

1728
    val = TPACKET_V2;
40✔
1729
    if (ptv->flags & AFP_TPACKET_V3) {
40✔
1730
        val = TPACKET_V3;
4✔
1731
    }
4✔
1732
    if (setsockopt(ptv->socket, SOL_PACKET, PACKET_VERSION, &val,
40✔
1733
                sizeof(val)) < 0) {
40✔
1734
        SCLogError("%s: failed to activate TPACKET_V2/TPACKET_V3 on packet socket: %s", devname,
×
1735
                strerror(errno));
×
1736
        return AFP_FATAL_ERROR;
×
1737
    }
×
1738

1739
#ifdef HAVE_HW_TIMESTAMPING
40✔
1740
    if (ptv->flags & AFP_ENABLE_HWTIMESTAMP) {
40✔
1741
        int req = SOF_TIMESTAMPING_RAW_HARDWARE;
×
1742
        if (setsockopt(ptv->socket, SOL_PACKET, PACKET_TIMESTAMP, (void *)&req, sizeof(req)) < 0) {
×
1743
            SCLogWarning("%s: failed to activate hardware timestamping on packet socket: %s",
×
1744
                    devname, strerror(errno));
×
1745
        } else {
×
1746
            SCLogConfig("%s: hardware timestamping enabled", devname);
×
1747
        }
×
1748
    } else {
40✔
1749
        SCLogConfig("%s: hardware timestamping disabled", devname);
40✔
1750
    }
40✔
1751
#endif
40✔
1752

1753
    /* Reserve head room for a VLAN header. One vlan is extracted from AFP header
1754
     * so one VLAN header length is enough. */
1755
    int reserve = VLAN_HEADER_LEN;
40✔
1756
    if (setsockopt(ptv->socket, SOL_PACKET, PACKET_RESERVE, (void *)&reserve, sizeof(reserve)) <
40✔
1757
            0) {
40✔
1758
        SCLogError("%s: failed to activate reserve on packet socket: %s", devname, strerror(errno));
×
1759
        return AFP_FATAL_ERROR;
×
1760
    }
×
1761

1762
    /* Allocate RX ring */
1763
    if (ptv->flags & AFP_TPACKET_V3) {
40✔
1764
        if (AFPComputeRingParamsV3(ptv) != 1) {
4✔
1765
            return AFP_FATAL_ERROR;
×
1766
        }
×
1767
        r = setsockopt(ptv->socket, SOL_PACKET, PACKET_RX_RING,
4✔
1768
                (void *) &ptv->req.v3, sizeof(ptv->req.v3));
4✔
1769
        if (r < 0) {
4✔
1770
            SCLogError("%s: failed to allocate RX Ring: %s", devname, strerror(errno));
×
1771
            return AFP_FATAL_ERROR;
×
1772
        }
×
1773
    } else {
36✔
1774
        if (ptv->v2_block_size) {
36✔
1775

1776
            if (AFPComputeRingParamsWithBlockSize(ptv, ptv->v2_block_size) != 1) {
×
1777
                SCLogError("%s: ring parameters are incorrect. Please file a bug report", devname);
×
1778
                return AFP_FATAL_ERROR;
×
1779
            }
×
1780

1781
            r = setsockopt(
×
1782
                    ptv->socket, SOL_PACKET, PACKET_RX_RING, (void *)&ptv->req, sizeof(ptv->req));
×
1783

1784
            if (r < 0) {
×
1785
                if (errno == ENOMEM) {
×
1786
                    SCLogError("%s: memory issue with ring parameters", devname);
×
1787
                    return AFP_FATAL_ERROR;
×
1788
                }
×
1789
                SCLogError("%s: failed to setup RX Ring: %s", devname, strerror(errno));
×
1790
                return AFP_FATAL_ERROR;
×
1791
            }
×
1792

1793
        } else {
36✔
1794
            for (order = AFP_BLOCK_SIZE_DEFAULT_ORDER; order >= 0; order--) {
36✔
1795
                if (AFPComputeRingParams(ptv, order) != 1) {
36✔
1796
                    SCLogError(
×
1797
                            "%s: ring parameters are incorrect. Please file a bug report", devname);
×
1798
                    return AFP_FATAL_ERROR;
×
1799
                }
×
1800

1801
                r = setsockopt(ptv->socket, SOL_PACKET, PACKET_RX_RING, (void *)&ptv->req,
36✔
1802
                        sizeof(ptv->req));
36✔
1803

1804
                if (r < 0) {
36✔
1805
                    if (errno == ENOMEM) {
×
1806
                        SCLogWarning("%s: memory issue with ring parameters. Retrying", devname);
×
1807
                        continue;
×
1808
                    }
×
1809
                    SCLogError("%s: failed to setup RX Ring: %s", devname, strerror(errno));
×
1810
                    return AFP_FATAL_ERROR;
×
1811
                } else {
36✔
1812
                    break;
36✔
1813
                }
36✔
1814
            }
36✔
1815
            if (order < 0) {
36✔
1816
                SCLogError("%s: failed to setup RX Ring (order 0 failed)", devname);
×
1817
                return AFP_FATAL_ERROR;
×
1818
            }
×
1819
        }
36✔
1820
    }
36✔
1821

1822
    /* Allocate the Ring */
1823
    if (ptv->flags & AFP_TPACKET_V3) {
40✔
1824
        ptv->ring_buflen = ptv->req.v3.tp_block_nr * ptv->req.v3.tp_block_size;
4✔
1825
    } else {
36✔
1826
        ptv->ring_buflen = ptv->req.v2.tp_block_nr * ptv->req.v2.tp_block_size;
36✔
1827
    }
36✔
1828
    mmap_flag = MAP_SHARED;
40✔
1829
    if (ptv->flags & AFP_MMAP_LOCKED)
40✔
1830
        mmap_flag |= MAP_LOCKED;
×
1831
    ptv->ring_buf = mmap(0, ptv->ring_buflen, PROT_READ|PROT_WRITE,
40✔
1832
            mmap_flag, ptv->socket, 0);
40✔
1833
    if (ptv->ring_buf == MAP_FAILED) {
40✔
1834
        SCLogError("%s: failed to mmap: %s", devname, strerror(errno));
×
1835
        goto mmap_err;
×
1836
    }
×
1837
    if (ptv->flags & AFP_TPACKET_V3) {
40✔
1838
        ptv->ring.v3 = SCMalloc(ptv->req.v3.tp_block_nr * sizeof(*ptv->ring.v3));
4✔
1839
        if (!ptv->ring.v3) {
4✔
1840
            SCLogError("%s: failed to alloc ring: %s", devname, strerror(errno));
×
1841
            goto postmmap_err;
×
1842
        }
×
1843
        for (i = 0; i < ptv->req.v3.tp_block_nr; ++i) {
32✔
1844
            ptv->ring.v3[i].iov_base = ptv->ring_buf + (i * ptv->req.v3.tp_block_size);
28✔
1845
            ptv->ring.v3[i].iov_len = ptv->req.v3.tp_block_size;
28✔
1846
        }
28✔
1847
    } else {
36✔
1848
        /* allocate a ring for each frame header pointer*/
1849
        ptv->ring.v2 = SCCalloc(ptv->req.v2.tp_frame_nr, sizeof(union thdr *));
36✔
1850
        if (ptv->ring.v2 == NULL) {
36✔
1851
            SCLogError("%s: failed to alloc ring: %s", devname, strerror(errno));
×
1852
            goto postmmap_err;
×
1853
        }
×
1854
        /* fill the header ring with proper frame ptr*/
1855
        ptv->frame_offset = 0;
36✔
1856
        for (i = 0; i < ptv->req.v2.tp_block_nr; ++i) {
1,472✔
1857
            void *base = &(ptv->ring_buf[i * ptv->req.v2.tp_block_size]);
1,436✔
1858
            unsigned int j;
1,436✔
1859
            for (j = 0; j < ptv->req.v2.tp_block_size / ptv->req.v2.tp_frame_size; ++j, ++ptv->frame_offset) {
28,508✔
1860
                (((union thdr **)ptv->ring.v2)[ptv->frame_offset]) = base;
27,072✔
1861
                base += ptv->req.v2.tp_frame_size;
27,072✔
1862
            }
27,072✔
1863
        }
1,436✔
1864
        ptv->frame_offset = 0;
36✔
1865
    }
36✔
1866

1867
    return 0;
40✔
1868

1869
postmmap_err:
×
1870
    munmap(ptv->ring_buf, ptv->ring_buflen);
×
1871
    if (ptv->ring.v2)
×
1872
        SCFree(ptv->ring.v2);
×
1873
    if (ptv->ring.v3)
×
1874
        SCFree(ptv->ring.v3);
×
1875
mmap_err:
×
1876
    /* Packet mmap does the cleaning when socket is closed */
1877
    return AFP_FATAL_ERROR;
×
1878
}
×
1879

1880
/** \brief test if we can use FANOUT. Older kernels like those in
1881
 *         CentOS6 have HAVE_PACKET_FANOUT defined but fail to work
1882
 */
1883
int AFPIsFanoutSupported(uint16_t cluster_id)
1884
{
14✔
1885
#ifdef HAVE_PACKET_FANOUT
14✔
1886
    int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
14✔
1887
    if (fd < 0)
14✔
1888
        return 0;
×
1889

1890
    uint32_t mode = PACKET_FANOUT_HASH | PACKET_FANOUT_FLAG_DEFRAG;
14✔
1891
    uint32_t option = (mode << 16) | cluster_id;
14✔
1892
    int r = setsockopt(fd, SOL_PACKET, PACKET_FANOUT,(void *)&option, sizeof(option));
14✔
1893
    close(fd);
14✔
1894

1895
    if (r < 0) {
14✔
1896
        SCLogError("fanout not supported by kernel: "
×
1897
                   "Kernel too old or cluster-id %d already in use.",
×
1898
                cluster_id);
×
1899
        return 0;
×
1900
    }
×
1901
    return 1;
14✔
1902
#else
1903
    return 0;
1904
#endif
1905
}
14✔
1906

1907
#ifdef HAVE_PACKET_EBPF
1908

1909
static int SockFanoutSeteBPF(AFPThreadVars *ptv)
1910
{
1911
    int pfd = ptv->ebpf_lb_fd;
1912
    if (pfd == -1) {
1913
        SCLogError("Fanout file descriptor is invalid");
1914
        return -1;
1915
    }
1916

1917
    if (setsockopt(ptv->socket, SOL_PACKET, PACKET_FANOUT_DATA, &pfd, sizeof(pfd))) {
1918
        SCLogError("Error setting ebpf");
1919
        return -1;
1920
    }
1921
    SCLogInfo("Activated eBPF on socket");
1922

1923
    return 0;
1924
}
1925

1926
static TmEcode SetEbpfFilter(AFPThreadVars *ptv)
1927
{
1928
    int pfd = ptv->ebpf_filter_fd;
1929
    if (pfd == -1) {
1930
        SCLogError("Filter file descriptor is invalid");
1931
        return TM_ECODE_FAILED;
1932
    }
1933

1934
    if (setsockopt(ptv->socket, SOL_SOCKET, SO_ATTACH_BPF, &pfd, sizeof(pfd))) {
1935
        SCLogError("Error setting ebpf: %s", strerror(errno));
1936
        return TM_ECODE_FAILED;
1937
    }
1938
    SCLogInfo("Activated eBPF filter on socket");
1939

1940
    return TM_ECODE_OK;
1941
}
1942
#endif
1943

1944
/** \param peer_update increment peers reached */
1945
static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose, const bool peer_update)
1946
{
40✔
1947
    int r;
40✔
1948
    int ret = AFP_FATAL_ERROR;
40✔
1949
    struct packet_mreq sock_params;
40✔
1950
    struct sockaddr_ll bind_address;
40✔
1951
    int if_idx;
40✔
1952

1953
    /* open socket */
1954
    ptv->socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
40✔
1955
    if (ptv->socket == -1) {
40✔
1956
        SCLogError("%s: failed to create socket: %s", devname, strerror(errno));
×
1957
        goto error;
×
1958
    }
×
1959

1960
    if_idx = AFPGetIfnumByDev(ptv->socket, devname, verbose);
40✔
1961
    if (if_idx == -1) {
40✔
1962
        goto socket_err;
×
1963
    }
×
1964

1965
    /* bind socket */
1966
    memset(&bind_address, 0, sizeof(bind_address));
40✔
1967
    bind_address.sll_family = AF_PACKET;
40✔
1968
    bind_address.sll_protocol = htons(ETH_P_ALL);
40✔
1969
    bind_address.sll_ifindex = if_idx;
40✔
1970
    if (bind_address.sll_ifindex == -1) {
40✔
1971
        if (verbose)
×
1972
            SCLogWarning("%s: device for found", devname);
×
1973
        ret = AFP_RECOVERABLE_ERROR;
×
1974
        goto socket_err;
×
1975
    }
×
1976

1977
    int if_flags = AFPGetDevFlags(ptv->socket, ptv->iface);
40✔
1978
    if (if_flags == -1) {
40✔
1979
        if (verbose) {
×
1980
            SCLogWarning("%s: failed to get interface flags", ptv->iface);
×
1981
        }
×
1982
        ret = AFP_RECOVERABLE_ERROR;
×
1983
        goto socket_err;
×
1984
    } else if ((if_flags & (IFF_UP | IFF_RUNNING)) == 0) {
40✔
1985
        if (verbose) {
×
1986
            SCLogWarning("%s: interface is down", ptv->iface);
×
1987
        }
×
1988
        ret = AFP_RECOVERABLE_ERROR;
×
1989
        goto socket_err;
×
1990
    }
×
1991

1992
    /* ignore outgoing packets on loopback interfaces */
1993
    if (if_flags & IFF_LOOPBACK)
40✔
1994
        ptv->pkttype_filter_mask |= BIT_U32(PACKET_OUTGOING);
×
1995

1996
    if (ptv->promisc != 0) {
40✔
1997
        /* Force promiscuous mode */
1998
        memset(&sock_params, 0, sizeof(sock_params));
40✔
1999
        sock_params.mr_type = PACKET_MR_PROMISC;
40✔
2000
        sock_params.mr_ifindex = bind_address.sll_ifindex;
40✔
2001
        r = setsockopt(ptv->socket, SOL_PACKET, PACKET_ADD_MEMBERSHIP,(void *)&sock_params, sizeof(sock_params));
40✔
2002
        if (r < 0) {
40✔
2003
            SCLogError("%s: failed to set promisc mode: %s", devname, strerror(errno));
×
2004
            goto socket_err;
×
2005
        }
×
2006
    }
40✔
2007

2008
    if (ptv->checksum_mode == CHECKSUM_VALIDATION_KERNEL) {
40✔
2009
        int val = 1;
40✔
2010
        if (setsockopt(ptv->socket, SOL_PACKET, PACKET_AUXDATA, &val,
40✔
2011
                    sizeof(val)) == -1 && errno != ENOPROTOOPT) {
40✔
2012
            SCLogWarning(
×
2013
                    "%s: 'kernel' checksum mode not supported, falling back to full mode", devname);
×
2014
            ptv->checksum_mode = CHECKSUM_VALIDATION_ENABLE;
×
2015
        }
×
2016
    }
40✔
2017

2018
    /* set socket recv buffer size */
2019
    if (ptv->buffer_size != 0) {
40✔
2020
        /*
2021
         * Set the socket buffer size to the specified value.
2022
         */
2023
        SCLogPerf("%s: setting socket buffer to %d", devname, ptv->buffer_size);
×
2024
        if (setsockopt(ptv->socket, SOL_SOCKET, SO_RCVBUF,
×
2025
                       &ptv->buffer_size,
×
2026
                       sizeof(ptv->buffer_size)) == -1) {
×
2027
            SCLogError("%s: failed to set buffer size to %d: %s", devname, ptv->buffer_size,
×
2028
                    strerror(errno));
×
2029
            goto socket_err;
×
2030
        }
×
2031
    }
×
2032

2033
    r = bind(ptv->socket, (struct sockaddr *)&bind_address, sizeof(bind_address));
40✔
2034
    if (r < 0) {
40✔
2035
        if (verbose) {
×
2036
            if (errno == ENETDOWN) {
×
2037
                SCLogWarning("%s: failed to bind socket, iface is down", devname);
×
2038
            } else {
×
2039
                SCLogWarning("%s: failed to bind socket: %s", devname, strerror(errno));
×
2040
            }
×
2041
        }
×
2042
        ret = AFP_RECOVERABLE_ERROR;
×
2043
        goto socket_err;
×
2044
    }
×
2045

2046

2047
#ifdef HAVE_PACKET_FANOUT
40✔
2048
    /* add bound socket to fanout group */
2049
    if (ptv->threads > 1) {
40✔
2050
        uint32_t mode = ptv->cluster_type;
40✔
2051
        uint16_t id = ptv->cluster_id;
40✔
2052
        uint32_t option = (mode << 16) | (id & 0xffff);
40✔
2053
        r = setsockopt(ptv->socket, SOL_PACKET, PACKET_FANOUT,(void *)&option, sizeof(option));
40✔
2054
        if (r < 0) {
40✔
2055
            SCLogError("%s: failed to set fanout mode: %s", devname, strerror(errno));
×
2056
            goto socket_err;
×
2057
        }
×
2058
    }
40✔
2059
#endif
40✔
2060

2061
#ifdef HAVE_PACKET_EBPF
2062
    if (ptv->cluster_type == PACKET_FANOUT_EBPF) {
2063
        r = SockFanoutSeteBPF(ptv);
2064
        if (r < 0) {
2065
            SCLogError("%s: failed to set eBPF: %s", devname, strerror(errno));
2066
            goto socket_err;
2067
        }
2068
    }
2069
#endif
2070
    /* bind() done, allow next thread to continue */
2071
    if (peer_update) {
40✔
2072
        AFPPeersListReachedInc();
40✔
2073
    }
40✔
2074
    ret = AFPSetupRing(ptv, devname);
40✔
2075
    if (ret != 0)
40✔
2076
        goto socket_err;
×
2077

2078
    SCLogDebug("Using interface '%s' via socket %d", (char *)devname, ptv->socket);
40✔
2079

2080
    ptv->datalink = AFPGetDevLinktype(ptv->socket, ptv->iface);
40✔
2081

2082
    TmEcode rc = AFPSetBPFFilter(ptv);
40✔
2083
    if (rc == TM_ECODE_FAILED) {
40✔
2084
        ret = AFP_FATAL_ERROR;
×
2085
        goto socket_err;
×
2086
    }
×
2087

2088
    /* Init is ok */
2089
    AFPSwitchState(ptv, AFP_STATE_UP);
40✔
2090
    return 0;
40✔
2091

2092
socket_err:
×
2093
    close(ptv->socket);
×
2094
    ptv->socket = -1;
×
2095
    if (ptv->flags & AFP_TPACKET_V3) {
×
2096
        if (ptv->ring.v3) {
×
2097
            SCFree(ptv->ring.v3);
×
2098
            ptv->ring.v3 = NULL;
×
2099
        }
×
2100
    } else {
×
2101
        if (ptv->ring.v2) {
×
2102
            SCFree(ptv->ring.v2);
×
2103
            ptv->ring.v2 = NULL;
×
2104
        }
×
2105
    }
×
2106

2107
error:
×
2108
    return -ret;
×
2109
}
×
2110

2111
TmEcode AFPSetBPFFilter(AFPThreadVars *ptv)
2112
{
40✔
2113
    struct bpf_program filter;
40✔
2114
    struct sock_fprog fcode;
40✔
2115
    int rc;
40✔
2116

2117
#ifdef HAVE_PACKET_EBPF
2118
    if (ptv->ebpf_filter_fd != -1) {
2119
        return SetEbpfFilter(ptv);
2120
    }
2121
#endif
2122

2123
    if (!ptv->bpf_filter)
40✔
2124
        return TM_ECODE_OK;
24✔
2125

2126
    SCLogInfo("%s: using BPF '%s'", ptv->iface, ptv->bpf_filter);
16✔
2127

2128
    char errbuf[PCAP_ERRBUF_SIZE];
16✔
2129
    if (SCBPFCompile(ptv->snaplen, /* snaplen_arg */
16✔
2130
                ptv->datalink,     /* linktype_arg */
16✔
2131
                &filter,           /* program */
16✔
2132
                ptv->bpf_filter,   /* const char *buf */
16✔
2133
                1,                 /* optimize */
16✔
2134
                0,                 /* mask */
16✔
2135
                errbuf, sizeof(errbuf)) == -1) {
16✔
2136
        SCLogError("%s: failed to compile BPF \"%s\": %s", ptv->iface, ptv->bpf_filter, errbuf);
×
2137
        return TM_ECODE_FAILED;
×
2138
    }
×
2139

2140
    if (filter.bf_len > USHRT_MAX) {
16✔
2141
        return TM_ECODE_FAILED;
×
2142
    }
×
2143
    fcode.len = (unsigned short)filter.bf_len;
16✔
2144
    fcode.filter = (struct sock_filter*)filter.bf_insns;
16✔
2145

2146
    rc = setsockopt(ptv->socket, SOL_SOCKET, SO_ATTACH_FILTER, &fcode, sizeof(fcode));
16✔
2147

2148
    SCBPFFree(&filter);
16✔
2149
    if(rc == -1) {
16✔
2150
        SCLogError("%s: failed to attach filter: %s", ptv->iface, strerror(errno));
×
2151
        return TM_ECODE_FAILED;
×
2152
    }
×
2153

2154
    return TM_ECODE_OK;
16✔
2155
}
16✔
2156

2157
#ifdef HAVE_PACKET_EBPF
2158
/**
2159
 * Insert a half flow in the kernel bypass table
2160
 *
2161
 * \param mapfd file descriptor of the protocol bypass table
2162
 * \param key data to use as key in the table
2163
 * \return 0 in case of error, 1 if success
2164
 */
2165
static int AFPInsertHalfFlow(int mapd, void *key, unsigned int nr_cpus)
2166
{
2167
    BPF_DECLARE_PERCPU(struct pair, value, nr_cpus);
2168
    unsigned int i;
2169

2170
    if (mapd == -1) {
2171
        return 0;
2172
    }
2173

2174
    /* We use a per CPU structure so we have to set an array of values as the kernel
2175
     * is not duplicating the data on each CPU by itself. */
2176
    for (i = 0; i < nr_cpus; i++) {
2177
        BPF_PERCPU(value, i).packets = 0;
2178
        BPF_PERCPU(value, i).bytes = 0;
2179
    }
2180
    if (bpf_map_update_elem(mapd, key, value, BPF_NOEXIST) != 0) {
2181
        switch (errno) {
2182
            /* no more place in the hash */
2183
            case E2BIG:
2184
                return 0;
2185
            /* no more place in the hash for some hardware bypass */
2186
            case EAGAIN:
2187
                return 0;
2188
            /* if we already have the key then bypass is a success */
2189
            case EEXIST:
2190
                return 1;
2191
            /* Not supposed to be there so issue a error */
2192
            default:
2193
                SCLogError("Can't update eBPF map: %s (%d)", strerror(errno), errno);
2194
                return 0;
2195
        }
2196
    }
2197
    return 1;
2198
}
2199

2200
static int AFPSetFlowStorage(Packet *p, int map_fd, void *key0, void* key1,
2201
                             int family)
2202
{
2203
    FlowBypassInfo *fc = FlowGetStorageById(p->flow, GetFlowBypassInfoID());
2204
    if (fc) {
2205
        if (fc->bypass_data != NULL) {
2206
            // bypass already activated
2207
            SCFree(key0);
2208
            SCFree(key1);
2209
            return 1;
2210
        }
2211
        EBPFBypassData *eb = SCCalloc(1, sizeof(EBPFBypassData));
2212
        if (eb == NULL) {
2213
            EBPFDeleteKey(map_fd, key0);
2214
            EBPFDeleteKey(map_fd, key1);
2215
            LiveDevAddBypassFail(p->livedev, 1, family);
2216
            SCFree(key0);
2217
            SCFree(key1);
2218
            return 0;
2219
        }
2220
        eb->key[0] = key0;
2221
        eb->key[1] = key1;
2222
        eb->mapfd = map_fd;
2223
        eb->cpus_count = p->afp_v.nr_cpus;
2224
        fc->BypassUpdate = EBPFBypassUpdate;
2225
        fc->BypassFree = EBPFBypassFree;
2226
        fc->bypass_data = eb;
2227
    } else {
2228
        EBPFDeleteKey(map_fd, key0);
2229
        EBPFDeleteKey(map_fd, key1);
2230
        LiveDevAddBypassFail(p->livedev, 1, family);
2231
        SCFree(key0);
2232
        SCFree(key1);
2233
        return 0;
2234
    }
2235

2236
    LiveDevAddBypassStats(p->livedev, 1, family);
2237
    LiveDevAddBypassSuccess(p->livedev, 1, family);
2238
    return 1;
2239
}
2240

2241
/**
2242
 * Bypass function for AF_PACKET capture in eBPF mode
2243
 *
2244
 * This function creates two half flows in the map shared with the kernel
2245
 * to trigger bypass.
2246
 *
2247
 * The implementation of bypass is done via an IPv4 and an IPv6 flow table.
2248
 * This table contains the list of half flows to bypass. The in-kernel filter
2249
 * will skip/drop the packet if they belong to a flow in one of the flows
2250
 * table.
2251
 *
2252
 * \param p the packet belonging to the flow to bypass
2253
 * \return 0 if unable to bypass, 1 if success
2254
 */
2255
static int AFPBypassCallback(Packet *p)
2256
{
2257
    SCLogDebug("Calling af_packet callback function");
2258
    /* Only bypass TCP and UDP */
2259
    if (!(PacketIsTCP(p) || PacketIsUDP(p))) {
2260
        return 0;
2261
    }
2262

2263
    /* If we don't have a flow attached to packet the eBPF map entries
2264
     * will be destroyed at first flow bypass manager pass as we won't
2265
     * find any associated entry */
2266
    if (p->flow == NULL) {
2267
        return 0;
2268
    }
2269
    /* Bypassing tunneled packets is currently not supported
2270
     * because we can't discard the inner packet only due to
2271
     * primitive parsing in eBPF */
2272
    if (PacketIsTunnel(p)) {
2273
        return 0;
2274
    }
2275
    if (PacketIsIPv4(p)) {
2276
        SCLogDebug("add an IPv4");
2277
        if (p->afp_v.v4_map_fd == -1) {
2278
            return 0;
2279
        }
2280
        struct flowv4_keys *keys[2];
2281
        keys[0] = SCCalloc(1, sizeof(struct flowv4_keys));
2282
        if (keys[0] == NULL) {
2283
            return 0;
2284
        }
2285
        keys[0]->src = htonl(GET_IPV4_SRC_ADDR_U32(p));
2286
        keys[0]->dst = htonl(GET_IPV4_DST_ADDR_U32(p));
2287
        keys[0]->port16[0] = p->sp;
2288
        keys[0]->port16[1] = p->dp;
2289
        keys[0]->vlan0 = p->vlan_id[0];
2290
        keys[0]->vlan1 = p->vlan_id[1];
2291

2292
        if (p->proto == IPPROTO_TCP) {
2293
            keys[0]->ip_proto = 1;
2294
        } else {
2295
            keys[0]->ip_proto = 0;
2296
        }
2297
        if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[0],
2298
                              p->afp_v.nr_cpus) == 0) {
2299
            LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2300
            SCFree(keys[0]);
2301
            return 0;
2302
        }
2303
        keys[1]= SCCalloc(1, sizeof(struct flowv4_keys));
2304
        if (keys[1] == NULL) {
2305
            EBPFDeleteKey(p->afp_v.v4_map_fd, keys[0]);
2306
            LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2307
            SCFree(keys[0]);
2308
            return 0;
2309
        }
2310
        keys[1]->src = htonl(GET_IPV4_DST_ADDR_U32(p));
2311
        keys[1]->dst = htonl(GET_IPV4_SRC_ADDR_U32(p));
2312
        keys[1]->port16[0] = p->dp;
2313
        keys[1]->port16[1] = p->sp;
2314
        keys[1]->vlan0 = p->vlan_id[0];
2315
        keys[1]->vlan1 = p->vlan_id[1];
2316

2317
        keys[1]->ip_proto = keys[0]->ip_proto;
2318
        if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[1],
2319
                              p->afp_v.nr_cpus) == 0) {
2320
            EBPFDeleteKey(p->afp_v.v4_map_fd, keys[0]);
2321
            LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2322
            SCFree(keys[0]);
2323
            SCFree(keys[1]);
2324
            return 0;
2325
        }
2326
        EBPFUpdateFlow(p->flow, p, NULL);
2327
        return AFPSetFlowStorage(p, p->afp_v.v4_map_fd, keys[0], keys[1], AF_INET);
2328
    }
2329
    /* For IPv6 case we don't handle extended header in eBPF */
2330
    if (PacketIsIPv6(p) && ((p->proto == IPPROTO_TCP) || (p->proto == IPPROTO_UDP))) {
2331
        int i;
2332
        if (p->afp_v.v6_map_fd == -1) {
2333
            return 0;
2334
        }
2335
        SCLogDebug("add an IPv6");
2336
        struct flowv6_keys *keys[2];
2337
        keys[0] = SCCalloc(1, sizeof(struct flowv6_keys));
2338
        if (keys[0] == NULL) {
2339
            LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2340
            return 0;
2341
        }
2342
        for (i = 0; i < 4; i++) {
2343
            keys[0]->src[i] = ntohl(GET_IPV6_SRC_ADDR(p)[i]);
2344
            keys[0]->dst[i] = ntohl(GET_IPV6_DST_ADDR(p)[i]);
2345
        }
2346
        keys[0]->port16[0] = p->sp;
2347
        keys[0]->port16[1] = p->dp;
2348
        keys[0]->vlan0 = p->vlan_id[0];
2349
        keys[0]->vlan1 = p->vlan_id[1];
2350

2351
        if (p->proto == IPPROTO_TCP) {
2352
            keys[0]->ip_proto = 1;
2353
        } else {
2354
            keys[0]->ip_proto = 0;
2355
        }
2356
        if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[0],
2357
                              p->afp_v.nr_cpus) == 0) {
2358
            LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2359
            SCFree(keys[0]);
2360
            return 0;
2361
        }
2362
        keys[1]= SCCalloc(1, sizeof(struct flowv6_keys));
2363
        if (keys[1] == NULL) {
2364
            EBPFDeleteKey(p->afp_v.v6_map_fd, keys[0]);
2365
            LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2366
            SCFree(keys[0]);
2367
            return 0;
2368
        }
2369
        for (i = 0; i < 4; i++) {
2370
            keys[1]->src[i] = ntohl(GET_IPV6_DST_ADDR(p)[i]);
2371
            keys[1]->dst[i] = ntohl(GET_IPV6_SRC_ADDR(p)[i]);
2372
        }
2373
        keys[1]->port16[0] = p->dp;
2374
        keys[1]->port16[1] = p->sp;
2375
        keys[1]->vlan0 = p->vlan_id[0];
2376
        keys[1]->vlan1 = p->vlan_id[1];
2377

2378
        keys[1]->ip_proto = keys[0]->ip_proto;
2379
        if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[1],
2380
                              p->afp_v.nr_cpus) == 0) {
2381
            EBPFDeleteKey(p->afp_v.v6_map_fd, keys[0]);
2382
            LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2383
            SCFree(keys[0]);
2384
            SCFree(keys[1]);
2385
            return 0;
2386
        }
2387
        if (p->flow)
2388
            EBPFUpdateFlow(p->flow, p, NULL);
2389
        return AFPSetFlowStorage(p, p->afp_v.v6_map_fd, keys[0], keys[1], AF_INET6);
2390
    }
2391
    return 0;
2392
}
2393

2394
/**
2395
 * Bypass function for AF_PACKET capture in XDP mode
2396
 *
2397
 * This function creates two half flows in the map shared with the kernel
2398
 * to trigger bypass. This function is similar to AFPBypassCallback() but
2399
 * the bytes order is changed for some data due to the way we get the data
2400
 * in the XDP case.
2401
 *
2402
 * \param p the packet belonging to the flow to bypass
2403
 * \return 0 if unable to bypass, 1 if success
2404
 */
2405
static int AFPXDPBypassCallback(Packet *p)
2406
{
2407
    SCLogDebug("Calling af_packet callback function");
2408
    /* Only bypass TCP and UDP */
2409
    if (!(PacketIsTCP(p) || PacketIsUDP(p))) {
2410
        return 0;
2411
    }
2412

2413
    /* If we don't have a flow attached to packet the eBPF map entries
2414
     * will be destroyed at first flow bypass manager pass as we won't
2415
     * find any associated entry */
2416
    if (p->flow == NULL) {
2417
        return 0;
2418
    }
2419
    /* Bypassing tunneled packets is currently not supported
2420
     * because we can't discard the inner packet only due to
2421
     * primitive parsing in eBPF */
2422
    if (PacketIsTunnel(p)) {
2423
        return 0;
2424
    }
2425
    if (PacketIsIPv4(p)) {
2426
        struct flowv4_keys *keys[2];
2427
        keys[0]= SCCalloc(1, sizeof(struct flowv4_keys));
2428
        if (keys[0] == NULL) {
2429
            LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2430
            return 0;
2431
        }
2432
        if (p->afp_v.v4_map_fd == -1) {
2433
            SCFree(keys[0]);
2434
            return 0;
2435
        }
2436
        keys[0]->src = p->src.addr_data32[0];
2437
        keys[0]->dst = p->dst.addr_data32[0];
2438
        /* In the XDP filter we get port from parsing of packet and not from skb
2439
         * (as in eBPF filter) so we need to pass from host to network order */
2440
        keys[0]->port16[0] = htons(p->sp);
2441
        keys[0]->port16[1] = htons(p->dp);
2442
        keys[0]->vlan0 = p->vlan_id[0];
2443
        keys[0]->vlan1 = p->vlan_id[1];
2444
        if (p->proto == IPPROTO_TCP) {
2445
            keys[0]->ip_proto = 1;
2446
        } else {
2447
            keys[0]->ip_proto = 0;
2448
        }
2449
        if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[0],
2450
                              p->afp_v.nr_cpus) == 0) {
2451
            LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2452
            SCFree(keys[0]);
2453
            return 0;
2454
        }
2455
        keys[1]= SCCalloc(1, sizeof(struct flowv4_keys));
2456
        if (keys[1] == NULL) {
2457
            EBPFDeleteKey(p->afp_v.v4_map_fd, keys[0]);
2458
            LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2459
            SCFree(keys[0]);
2460
            return 0;
2461
        }
2462
        keys[1]->src = p->dst.addr_data32[0];
2463
        keys[1]->dst = p->src.addr_data32[0];
2464
        keys[1]->port16[0] = htons(p->dp);
2465
        keys[1]->port16[1] = htons(p->sp);
2466
        keys[1]->vlan0 = p->vlan_id[0];
2467
        keys[1]->vlan1 = p->vlan_id[1];
2468
        keys[1]->ip_proto = keys[0]->ip_proto;
2469
        if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[1],
2470
                              p->afp_v.nr_cpus) == 0) {
2471
            EBPFDeleteKey(p->afp_v.v4_map_fd, keys[0]);
2472
            LiveDevAddBypassFail(p->livedev, 1, AF_INET);
2473
            SCFree(keys[0]);
2474
            SCFree(keys[1]);
2475
            return 0;
2476
        }
2477
        return AFPSetFlowStorage(p, p->afp_v.v4_map_fd, keys[0], keys[1], AF_INET);
2478
    }
2479
    /* For IPv6 case we don't handle extended header in eBPF */
2480
    if (PacketIsIPv6(p) && ((p->proto == IPPROTO_TCP) || (p->proto == IPPROTO_UDP))) {
2481
        SCLogDebug("add an IPv6");
2482
        if (p->afp_v.v6_map_fd == -1) {
2483
            return 0;
2484
        }
2485
        int i;
2486
        struct flowv6_keys *keys[2];
2487
        keys[0] = SCCalloc(1, sizeof(struct flowv6_keys));
2488
        if (keys[0] == NULL) {
2489
            return 0;
2490
        }
2491

2492
        for (i = 0; i < 4; i++) {
2493
            keys[0]->src[i] = GET_IPV6_SRC_ADDR(p)[i];
2494
            keys[0]->dst[i] = GET_IPV6_DST_ADDR(p)[i];
2495
        }
2496
        keys[0]->port16[0] = htons(p->sp);
2497
        keys[0]->port16[1] = htons(p->dp);
2498
        keys[0]->vlan0 = p->vlan_id[0];
2499
        keys[0]->vlan1 = p->vlan_id[1];
2500
        if (p->proto == IPPROTO_TCP) {
2501
            keys[0]->ip_proto = 1;
2502
        } else {
2503
            keys[0]->ip_proto = 0;
2504
        }
2505
        if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[0],
2506
                              p->afp_v.nr_cpus) == 0) {
2507
            LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2508
            SCFree(keys[0]);
2509
            return 0;
2510
        }
2511
        keys[1]= SCCalloc(1, sizeof(struct flowv6_keys));
2512
        if (keys[1] == NULL) {
2513
            EBPFDeleteKey(p->afp_v.v6_map_fd, keys[0]);
2514
            LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2515
            SCFree(keys[0]);
2516
            return 0;
2517
        }
2518
        for (i = 0; i < 4; i++) {
2519
            keys[1]->src[i] = GET_IPV6_DST_ADDR(p)[i];
2520
            keys[1]->dst[i] = GET_IPV6_SRC_ADDR(p)[i];
2521
        }
2522
        keys[1]->port16[0] = htons(p->dp);
2523
        keys[1]->port16[1] = htons(p->sp);
2524
        keys[1]->vlan0 = p->vlan_id[0];
2525
        keys[1]->vlan1 = p->vlan_id[1];
2526
        keys[1]->ip_proto = keys[0]->ip_proto;
2527
        if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[1],
2528
                              p->afp_v.nr_cpus) == 0) {
2529
            EBPFDeleteKey(p->afp_v.v6_map_fd, keys[0]);
2530
            LiveDevAddBypassFail(p->livedev, 1, AF_INET6);
2531
            SCFree(keys[0]);
2532
            SCFree(keys[1]);
2533
            return 0;
2534
        }
2535
        return AFPSetFlowStorage(p, p->afp_v.v6_map_fd, keys[0], keys[1], AF_INET6);
2536
    }
2537
    return 0;
2538
}
2539

2540
bool g_flowv4_ok = true;
2541
bool g_flowv6_ok = true;
2542

2543
#endif /* HAVE_PACKET_EBPF */
2544

2545
/**
2546
 * \brief Init function for ReceiveAFP.
2547
 *
2548
 * \param tv pointer to ThreadVars
2549
 * \param initdata pointer to the interface passed from the user
2550
 * \param data pointer gets populated with AFPThreadVars
2551
 *
2552
 * \todo Create a general AFP setup function.
2553
 */
2554
TmEcode ReceiveAFPThreadInit(ThreadVars *tv, const void *initdata, void **data)
2555
{
40✔
2556
    SCEnter();
40✔
2557
    AFPIfaceConfig *afpconfig = (AFPIfaceConfig *)initdata;
40✔
2558

2559
    if (initdata == NULL) {
40✔
2560
        SCLogError("initdata == NULL");
×
2561
        SCReturnInt(TM_ECODE_FAILED);
×
2562
    }
×
2563

2564
    AFPThreadVars *ptv = SCCalloc(1, sizeof(AFPThreadVars));
40✔
2565
    if (unlikely(ptv == NULL)) {
40✔
2566
        afpconfig->DerefFunc(afpconfig);
×
2567
        SCReturnInt(TM_ECODE_FAILED);
×
2568
    }
×
2569

2570
    ptv->tv = tv;
40✔
2571

2572
    strlcpy(ptv->iface, afpconfig->iface, AFP_IFACE_NAME_LENGTH);
40✔
2573
    ptv->iface[AFP_IFACE_NAME_LENGTH - 1]= '\0';
40✔
2574

2575
    ptv->livedev = LiveGetDevice(ptv->iface);
40✔
2576
    if (ptv->livedev == NULL) {
40✔
2577
        SCLogError("Unable to find Live device");
×
2578
        SCFree(ptv);
×
2579
        SCReturnInt(TM_ECODE_FAILED);
×
2580
    }
×
2581

2582
    ptv->buffer_size = afpconfig->buffer_size;
40✔
2583
    ptv->ring_size = afpconfig->ring_size;
40✔
2584
    ptv->v2_block_size = afpconfig->v2_block_size;
40✔
2585
    ptv->block_size = afpconfig->block_size;
40✔
2586
    ptv->block_timeout = afpconfig->block_timeout;
40✔
2587

2588
    ptv->promisc = afpconfig->promisc;
40✔
2589
    ptv->checksum_mode = afpconfig->checksum_mode;
40✔
2590
    ptv->bpf_filter = NULL;
40✔
2591

2592
    ptv->threads = 1;
40✔
2593
#ifdef HAVE_PACKET_FANOUT
40✔
2594
    ptv->cluster_type = PACKET_FANOUT_LB;
40✔
2595
    ptv->cluster_id = 1;
40✔
2596
    /* We only set cluster info if the number of reader threads is greater than 1 */
2597
    if (afpconfig->threads > 1) {
40✔
2598
        ptv->cluster_id = afpconfig->cluster_id;
40✔
2599
        ptv->cluster_type = afpconfig->cluster_type;
40✔
2600
        ptv->threads = afpconfig->threads;
40✔
2601
    }
40✔
2602
#endif
40✔
2603
    ptv->flags = afpconfig->flags;
40✔
2604

2605
    if (afpconfig->bpf_filter) {
40✔
2606
        ptv->bpf_filter = afpconfig->bpf_filter;
16✔
2607
    }
16✔
2608
#ifdef HAVE_PACKET_EBPF
2609
    ptv->ebpf_lb_fd = afpconfig->ebpf_lb_fd;
2610
    ptv->ebpf_filter_fd = afpconfig->ebpf_filter_fd;
2611
    ptv->xdp_mode = afpconfig->xdp_mode;
2612
    ptv->ebpf_t_config.cpus_count = UtilCpuGetNumProcessorsConfigured();
2613

2614
    if (ptv->flags & (AFP_BYPASS|AFP_XDPBYPASS)) {
2615
        ptv->v4_map_fd = EBPFGetMapFDByName(ptv->iface, "flow_table_v4");
2616
        if (ptv->v4_map_fd == -1) {
2617
            if (!g_flowv4_ok) {
2618
                SCLogError("Can't find eBPF map fd for '%s'", "flow_table_v4");
2619
                g_flowv4_ok = true;
2620
            }
2621
        }
2622
        ptv->v6_map_fd = EBPFGetMapFDByName(ptv->iface, "flow_table_v6");
2623
        if (ptv->v6_map_fd  == -1) {
2624
            if (g_flowv6_ok) {
2625
                SCLogError("Can't find eBPF map fd for '%s'", "flow_table_v6");
2626
                g_flowv6_ok = false;
2627
            }
2628
        }
2629
    }
2630
    ptv->ebpf_t_config = afpconfig->ebpf_t_config;
2631
#endif
2632

2633
#ifdef PACKET_STATISTICS
40✔
2634
    ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets", &ptv->tv->stats);
40✔
2635
    ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops", &ptv->tv->stats);
40✔
2636
    ptv->capture_errors = StatsRegisterCounter("capture.errors", &ptv->tv->stats);
40✔
2637

2638
    ptv->afpacket_spin = StatsRegisterAvgCounter("capture.afpacket.busy_loop_avg", &ptv->tv->stats);
40✔
2639

2640
    ptv->capture_afp_poll = StatsRegisterCounter("capture.afpacket.polls", &ptv->tv->stats);
40✔
2641
    ptv->capture_afp_poll_signal =
40✔
2642
            StatsRegisterCounter("capture.afpacket.poll_signal", &ptv->tv->stats);
40✔
2643
    ptv->capture_afp_poll_timeout =
40✔
2644
            StatsRegisterCounter("capture.afpacket.poll_timeout", &ptv->tv->stats);
40✔
2645
    ptv->capture_afp_poll_data =
40✔
2646
            StatsRegisterCounter("capture.afpacket.poll_data", &ptv->tv->stats);
40✔
2647
    ptv->capture_afp_poll_err =
40✔
2648
            StatsRegisterCounter("capture.afpacket.poll_errors", &ptv->tv->stats);
40✔
2649
    ptv->capture_afp_send_err =
40✔
2650
            StatsRegisterCounter("capture.afpacket.send_errors", &ptv->tv->stats);
40✔
2651
#endif
40✔
2652

2653
    ptv->copy_mode = afpconfig->copy_mode;
40✔
2654
    if (ptv->copy_mode != AFP_COPY_MODE_NONE) {
40✔
2655
        strlcpy(ptv->out_iface, afpconfig->out_iface, AFP_IFACE_NAME_LENGTH);
24✔
2656
        ptv->out_iface[AFP_IFACE_NAME_LENGTH - 1]= '\0';
24✔
2657
        /* Warn about BPF filter consequence */
2658
        if (ptv->bpf_filter) {
24✔
2659
            SCLogWarning("Enabling a BPF filter in IPS mode result"
×
2660
                         " in dropping all non matching packets.");
×
2661
        }
×
2662
    }
24✔
2663

2664

2665
    if (AFPPeersListAdd(ptv) == TM_ECODE_FAILED) {
40✔
2666
        SCFree(ptv);
×
2667
        afpconfig->DerefFunc(afpconfig);
×
2668
        SCReturnInt(TM_ECODE_FAILED);
×
2669
    }
×
2670

2671
    *data = (void *)ptv;
40✔
2672

2673
    afpconfig->DerefFunc(afpconfig);
40✔
2674

2675
    /* If kernel is older than 3.0, VLAN is not stripped so we don't
2676
     * get the info from packet extended header but we will use a standard
2677
     * parsing of packet data (See Linux commit bcc6d47903612c3861201cc3a866fb604f26b8b2) */
2678
    if (SCKernelVersionIsAtLeast(3, 0)) {
40✔
2679
        ptv->flags |= AFP_VLAN_IN_HEADER;
40✔
2680
    }
40✔
2681

2682
    SCReturnInt(TM_ECODE_OK);
40✔
2683
}
40✔
2684

2685
/**
2686
 * \brief This function prints stats to the screen at exit.
2687
 * \param tv pointer to ThreadVars
2688
 * \param data pointer that gets cast into AFPThreadVars for ptv
2689
 */
2690
void ReceiveAFPThreadExitStats(ThreadVars *tv, void *data)
2691
{
40✔
2692
    SCEnter();
40✔
2693
    AFPThreadVars *ptv = (AFPThreadVars *)data;
40✔
2694

2695
#ifdef PACKET_STATISTICS
40✔
2696
    AFPDumpCounters(ptv);
40✔
2697
    SCLogPerf("%s: (%s) kernel: Packets %" PRIu64 ", dropped %" PRIu64 "", ptv->iface, tv->name,
40✔
2698
            StatsCounterGetLocalValue(&tv->stats, ptv->capture_kernel_packets),
40✔
2699
            StatsCounterGetLocalValue(&tv->stats, ptv->capture_kernel_drops));
40✔
2700
#endif
40✔
2701
}
40✔
2702

2703
/**
2704
 * \brief DeInit function closes af packet socket at exit.
2705
 * \param tv pointer to ThreadVars
2706
 * \param data pointer that gets cast into AFPThreadVars for ptv
2707
 */
2708
TmEcode ReceiveAFPThreadDeinit(ThreadVars *tv, void *data)
2709
{
40✔
2710
    AFPThreadVars *ptv = (AFPThreadVars *)data;
40✔
2711

2712
    AFPSwitchState(ptv, AFP_STATE_DOWN);
40✔
2713

2714
#ifdef HAVE_PACKET_XDP
2715
    if ((ptv->ebpf_t_config.flags & EBPF_XDP_CODE) &&
2716
        (!(ptv->ebpf_t_config.flags & EBPF_PINNED_MAPS))) {
2717
        EBPFSetupXDP(ptv->iface, -1, ptv->xdp_mode);
2718
    }
2719
#endif
2720

2721
    ptv->bpf_filter = NULL;
40✔
2722
    if ((ptv->flags & AFP_TPACKET_V3) && ptv->ring.v3) {
40✔
2723
        SCFree(ptv->ring.v3);
4✔
2724
    } else {
36✔
2725
        if (ptv->ring.v2)
36✔
2726
            SCFree(ptv->ring.v2);
36✔
2727
    }
36✔
2728

2729
    SCFree(ptv);
40✔
2730
    SCReturnInt(TM_ECODE_OK);
40✔
2731
}
40✔
2732

2733
/** \internal
2734
 *  \brief add a VLAN header into the raw data for inspection, logging
2735
 *         and sending out in IPS mode
2736
 *
2737
 *  The kernel doesn't provide the first VLAN header the raw packet data,
2738
 *  but instead feeds it to us through meta data. For logging and IPS
2739
 *  we need to put it back into the raw data. Luckily there is some head
2740
 *  room in the original data so its enough to move the ethernet header
2741
 *  a bit to make space for the VLAN header.
2742
 */
2743
static void UpdateRawDataForVLANHdr(Packet *p)
2744
{
×
2745
    if (p->afp_v.vlan_tci != 0) {
×
2746
        uint8_t *pstart = GET_PKT_DATA(p) - VLAN_HEADER_LEN;
×
2747
        uint32_t plen = GET_PKT_LEN(p) + VLAN_HEADER_LEN;
×
2748
        /* move ethernet addresses */
2749
        memmove(pstart, GET_PKT_DATA(p), 2 * ETH_ALEN);
×
2750
        /* write vlan info */
2751
        *(uint16_t *)(pstart + 2 * ETH_ALEN) = htons(0x8100);
×
2752
        *(uint16_t *)(pstart + 2 * ETH_ALEN + 2) = htons(p->afp_v.vlan_tci);
×
2753

2754
        /* update the packet raw data pointer to start at the new offset */
2755
        (void)PacketSetData(p, pstart, plen);
×
2756
        /* update ethernet header pointer to point to the new start of the data */
2757
        p->l2.hdrs.ethh = (void *)pstart;
×
2758
    }
×
2759
}
×
2760

2761
/**
2762
 * \brief This function passes off to link type decoders.
2763
 *
2764
 * DecodeAFP decodes packets from AF_PACKET and passes
2765
 * them off to the proper link type decoder.
2766
 *
2767
 * \param t pointer to ThreadVars
2768
 * \param p pointer to the current packet
2769
 * \param data pointer that gets cast into AFPThreadVars for ptv
2770
 */
2771
TmEcode DecodeAFP(ThreadVars *tv, Packet *p, void *data)
2772
{
19,535✔
2773
    SCEnter();
19,535✔
2774

2775
    const bool afp_vlan_hdr = p->vlan_idx != 0;
19,535✔
2776
    DecodeThreadVars *dtv = (DecodeThreadVars *)data;
19,535✔
2777

2778
    DEBUG_VALIDATE_BUG_ON(PKT_IS_PSEUDOPKT(p));
19,535✔
2779

2780
    /* update counters */
2781
    DecodeUpdatePacketCounters(tv, dtv, p);
19,535✔
2782

2783
    /* call the decoder */
2784
    DecodeLinkLayer(tv, dtv, p->datalink, p, GET_PKT_DATA(p), GET_PKT_LEN(p));
19,535✔
2785
    /* post-decoding put vlan hdr back into the raw data) */
2786
    if (afp_vlan_hdr) {
19,535✔
2787
        StatsCounterIncr(&tv->stats, dtv->counter_vlan);
×
2788
        UpdateRawDataForVLANHdr(p);
×
2789
    }
×
2790

2791
    PacketDecodeFinalize(tv, dtv, p);
19,535✔
2792

2793
    SCReturnInt(TM_ECODE_OK);
19,535✔
2794
}
19,535✔
2795

2796
TmEcode DecodeAFPThreadInit(ThreadVars *tv, const void *initdata, void **data)
2797
{
40✔
2798
    SCEnter();
40✔
2799
    DecodeThreadVars *dtv = DecodeThreadVarsAlloc(tv);
40✔
2800
    if (dtv == NULL)
40✔
2801
        SCReturnInt(TM_ECODE_FAILED);
×
2802

2803
    DecodeRegisterPerfCounters(dtv, tv);
40✔
2804

2805
    *data = (void *)dtv;
40✔
2806

2807
    SCReturnInt(TM_ECODE_OK);
40✔
2808
}
40✔
2809

2810
TmEcode DecodeAFPThreadDeinit(ThreadVars *tv, void *data)
2811
{
40✔
2812
    if (data != NULL)
40✔
2813
        DecodeThreadVarsFree(tv, data);
40✔
2814
    SCReturnInt(TM_ECODE_OK);
40✔
2815
}
40✔
2816

2817
#endif /* HAVE_AF_PACKET */
2818
/* eof */
2819
/**
2820
 * @}
2821
 */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc