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.
pull/2091/head
Eric Leblond 9 years ago committed by Victor Julien
parent 876b356bbe
commit 7fea0ec6f9

@ -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;

Loading…
Cancel
Save