From: Eric Leblond Date: Tue, 12 Apr 2016 09:46:43 +0000 (+0200) Subject: af-packet: reset stats at start of capture X-Git-Tag: suricata-3.1RC1~99 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7fea0ec6f9c704a27db0c78c039bfd191f79d906;p=thirdparty%2Fsuricata.git af-packet: reset stats at start of capture We can loose packets during setup because we are reading nothing. So it is logical to discard the counter at start of capture to start from a clean state. This means we don't need to account the drop at start. But the stats call that will reset the drop counts will also return and reset the packets count. So we need to know how many packets we really have. This is in fact the number of packets coming from the stats call minus the number of discarded packets and the drop count. All the other packets will have to be read. --- diff --git a/src/source-af-packet.c b/src/source-af-packet.c index a993fddd70..7e1aa5444a 100644 --- a/src/source-af-packet.c +++ b/src/source-af-packet.c @@ -1113,7 +1113,8 @@ void AFPSwitchState(AFPThreadVars *ptv, int state) } } -static int AFPReadAndDiscard(AFPThreadVars *ptv, struct timeval *synctv) +static int AFPReadAndDiscard(AFPThreadVars *ptv, struct timeval *synctv, + uint64_t *discarded_pkts) { struct sockaddr_ll from; struct iovec iov; @@ -1155,7 +1156,8 @@ static int AFPReadAndDiscard(AFPThreadVars *ptv, struct timeval *synctv) return 0; } -static int AFPReadAndDiscardFromRing(AFPThreadVars *ptv, struct timeval *synctv) +static int AFPReadAndDiscardFromRing(AFPThreadVars *ptv, struct timeval *synctv, + uint64_t *discarded_pkts) { union thdr h; @@ -1163,26 +1165,30 @@ static int AFPReadAndDiscardFromRing(AFPThreadVars *ptv, struct timeval *synctv) return 1; } - /* Ignore system for tpacket_v3 */ if (ptv->flags & AFP_TPACKET_V3) { + struct tpacket_block_desc *pbd; + pbd = (struct tpacket_block_desc *) ptv->ring_v3[ptv->frame_offset].iov_base; + *discarded_pkts += pbd->hdr.bh1.num_pkts; + AFPFlushBlock(pbd); + ptv->frame_offset = (ptv->frame_offset + 1) % ptv->req3.tp_block_nr; return 1; - } - - /* Read packet from ring */ - h.raw = (((union thdr **)ptv->ring_v2)[ptv->frame_offset]); - if (h.raw == NULL) { - return -1; - } - - if (((time_t)h.h2->tp_sec > synctv->tv_sec) || - ((time_t)h.h2->tp_sec == synctv->tv_sec && - (suseconds_t) (h.h2->tp_nsec / 1000) > synctv->tv_usec)) { - return 1; - } + } else { + /* Read packet from ring */ + h.raw = (((union thdr **)ptv->ring_v2)[ptv->frame_offset]); + if (h.raw == NULL) { + return -1; + } + (*discarded_pkts)++; + if (((time_t)h.h2->tp_sec > synctv->tv_sec) || + ((time_t)h.h2->tp_sec == synctv->tv_sec && + (suseconds_t) (h.h2->tp_nsec / 1000) > synctv->tv_usec)) { + return 1; + } - h.h2->tp_status = TP_STATUS_KERNEL; - if (++ptv->frame_offset >= ptv->req.tp_frame_nr) { - ptv->frame_offset = 0; + h.h2->tp_status = TP_STATUS_KERNEL; + if (++ptv->frame_offset >= ptv->req.tp_frame_nr) { + ptv->frame_offset = 0; + } } @@ -1198,7 +1204,7 @@ static int AFPReadAndDiscardFromRing(AFPThreadVars *ptv, struct timeval *synctv) * * \retval r 1 = happy, otherwise unhappy */ -static int AFPSynchronizeStart(AFPThreadVars *ptv) +static int AFPSynchronizeStart(AFPThreadVars *ptv, uint64_t *discarded_pkts) { int r; struct timeval synctv; @@ -1223,9 +1229,9 @@ static int AFPSynchronizeStart(AFPThreadVars *ptv) gettimeofday(&synctv, NULL); } if (ptv->flags & AFP_RING_MODE) { - r = AFPReadAndDiscardFromRing(ptv, &synctv); + r = AFPReadAndDiscardFromRing(ptv, &synctv, discarded_pkts); } else { - r = AFPReadAndDiscard(ptv, &synctv); + r = AFPReadAndDiscard(ptv, &synctv, discarded_pkts); } SCLogDebug("Discarding on %s", ptv->tv->name); switch (r) { @@ -1292,6 +1298,7 @@ TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot) time_t last_dump = 0; struct timeval current_time; int (*AFPReadFunc) (AFPThreadVars *); + uint64_t discarded_pkts = 0; ptv->slot = s->slot_next; @@ -1331,8 +1338,25 @@ TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot) if (ptv->afp_state == AFP_STATE_UP) { SCLogDebug("Thread %s using socket %d", tv->name, ptv->socket); if ((ptv->flags & AFP_TPACKET_V3) != 0) { - AFPSynchronizeStart(ptv); + AFPSynchronizeStart(ptv, &discarded_pkts); } + /* let's reset counter as we will start the capture at the + * next function call */ +#ifdef PACKET_STATISTICS + struct tpacket_stats kstats; + socklen_t len = sizeof (struct tpacket_stats); + if (getsockopt(ptv->socket, SOL_PACKET, PACKET_STATISTICS, + &kstats, &len) > -1) { + uint64_t pkts = 0; + SCLogDebug("(%s) Kernel socket startup: Packets %" PRIu32 + ", dropped %" PRIu32 "", + ptv->tv->name, + kstats.tp_packets, kstats.tp_drops); + pkts = kstats.tp_packets - discarded_pkts - kstats.tp_drops; + StatsAddUI64(ptv->tv, ptv->capture_kernel_packets, pkts); + (void) SC_ATOMIC_ADD(ptv->livedev->pkts, pkts); + } +#endif } fds.fd = ptv->socket;