Changeset ed6304c5


Ignore:
Timestamp:
02/13/15 18:35:14 (6 years ago)
Author:
Richard Sanger <rsangerarj@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
3e89670
Parents:
1ebc4bd
Message:

For linux formats int/ring also use dev stats from /proc/net/dev to report
dropped packets.

This accounts for packets that dont even reach the kernel. The drop count
now matches 100% with sent packets.

There could be some slight discrepancies caused packets received between
opening/closing the socket and when we make our call to /proc/net/dev.
However this is a lot more realistic than previous numbers.

We might also be able to caclulate filtered packets from these numbers.

Location:
lib
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • lib/format_linux_common.c

    r6cf3ca0 red6304c5  
    225225                       FORMAT_DATA->req.tp_block_nr);
    226226        stream->rx_ring = MAP_FAILED;
     227        FORMAT_DATA->dev_stats.if_name[0] = 0;
     228}
     229
     230#define REPEAT_16(x) x x x x x x x x x x x x x x x x
     231#define xstr(s) str(s)
     232#define str(s) #s
     233
     234/* These don't typically reset however an interface does exist to reset them */
     235static int linuxcommon_get_dev_statisitics(libtrace_t *libtrace, struct linux_dev_stats *stats) {
     236        FILE *file;
     237        char line[1024];
     238        struct linux_dev_stats tmp_stats;
     239
     240        file = fopen("/proc/net/dev","r");
     241        if (file == NULL) {
     242                return -1;
     243        }
     244
     245        /* Skip 2 header lines */
     246        fgets(line, sizeof(line), file);
     247        fgets(line, sizeof(line), file);
     248
     249        while (!(feof(file)||ferror(file))) {
     250                int tot;
     251                fgets(line, sizeof(line), file);
     252                tot = sscanf(line, " %"xstr(IF_NAMESIZE)"[^:]:" REPEAT_16(" %"SCNd64),
     253                             tmp_stats.if_name,
     254                             &tmp_stats.rx_bytes,
     255                             &tmp_stats.rx_bytes,
     256                             &tmp_stats.rx_errors,
     257                             &tmp_stats.rx_drops,
     258                             &tmp_stats.rx_fifo,
     259                             &tmp_stats.rx_frame,
     260                             &tmp_stats.rx_compressed,
     261                             &tmp_stats.rx_multicast,
     262                             &tmp_stats.tx_bytes,
     263                             &tmp_stats.tx_packets,
     264                             &tmp_stats.tx_errors,
     265                             &tmp_stats.tx_drops,
     266                             &tmp_stats.tx_fifo,
     267                             &tmp_stats.tx_colls,
     268                             &tmp_stats.tx_carrier,
     269                             &tmp_stats.tx_compressed);
     270                if (tot != 17)
     271                        continue;
     272                if (strncmp(tmp_stats.if_name, libtrace->uridata, IF_NAMESIZE) == 0) {
     273                        *stats = tmp_stats;
     274                        fclose(file);
     275                        return 0;
     276                }
     277        }
     278        fclose(file);
     279        return -1;
    227280}
    228281
     
    364417
    365418        FORMAT_DATA->stats_valid = 0;
     419        if (linuxcommon_get_dev_statisitics(libtrace, &FORMAT_DATA->dev_stats) != 0) {
     420                /* Mark this as bad */
     421                FORMAT_DATA->dev_stats.if_name[0] = 0;
     422        }
    366423
    367424        return 0;
     
    474531}
    475532
    476 static void linuxcommon_update_statistics(libtrace_t *libtrace) {
     533/* These counters reset with each read */
     534static void linuxcommon_update_socket_statistics(libtrace_t *libtrace) {
    477535        struct tpacket_stats stats;
    478536        size_t i;
     
    494552                                } else {
    495553                                        FORMAT_DATA->stats.tp_drops += stats.tp_drops;
    496                                         FORMAT_DATA->stats.tp_drops += stats.tp_packets;
     554                                        FORMAT_DATA->stats.tp_packets += stats.tp_packets;
    497555                                }
    498556                        } else {
     
    512570                return UINT64_MAX;
    513571        }
    514         linuxcommon_update_statistics(libtrace);
     572        linuxcommon_update_socket_statistics(libtrace);
    515573        if (FORMAT_DATA->stats_valid)
    516574                return FORMAT_DATA->stats.tp_packets;
     
    526584 */
    527585uint64_t linuxcommon_get_dropped_packets(libtrace_t *libtrace) {
     586        struct linux_dev_stats dev_stats;
     587        uint64_t adjustment = 0;
    528588        if (libtrace->format_data == NULL)
    529589                return UINT64_MAX;
     
    533593                return UINT64_MAX;
    534594        }
    535         linuxcommon_update_statistics(libtrace);
     595        // Do we have starting stats to compare to?
     596        if (FORMAT_DATA->dev_stats.if_name[0] != 0) {
     597                if (linuxcommon_get_dev_statisitics(libtrace, &dev_stats) == 0) {
     598                        adjustment = dev_stats.rx_drops - FORMAT_DATA->dev_stats.rx_drops;
     599                }
     600        }
     601        linuxcommon_update_socket_statistics(libtrace);
    536602        if (FORMAT_DATA->stats_valid)
    537                 return FORMAT_DATA->stats.tp_drops;
     603                return FORMAT_DATA->stats.tp_drops + adjustment;
    538604        else
    539605                return UINT64_MAX;
  • lib/format_linux_common.h

    r6cf3ca0 red6304c5  
    172172};
    173173
     174
     175/* A structure we use to hold statistic counters from the network cards
     176 * as accessed via the /proc/net/dev
     177 */
     178struct linux_dev_stats {
     179        char if_name[IF_NAMESIZE];
     180        uint64_t rx_bytes;
     181        uint64_t rx_packets;
     182        uint64_t rx_errors;
     183        uint64_t rx_drops;
     184        uint64_t rx_fifo;
     185        uint64_t rx_frame;
     186        uint64_t rx_compressed;
     187        uint64_t rx_multicast;
     188        uint64_t tx_bytes;
     189        uint64_t tx_packets;
     190        uint64_t tx_errors;
     191        uint64_t tx_drops;
     192        uint64_t tx_fifo;
     193        uint64_t tx_colls;
     194        uint64_t tx_carrier;
     195        uint64_t tx_compressed;
     196};
     197
    174198/* Note that this structure is passed over the wire in rt encapsulation, and
    175199 * thus we need to be careful with data sizes.  timeval's and timespec's
     
    188212        /* Statistics for the capture process, e.g. dropped packet counts */
    189213        struct tpacket_stats stats;
     214        /* Statistics for the NIC rather than the socket */
     215        struct linux_dev_stats dev_stats;
    190216        /* Flag indicating whether the statistics are current or not */
    191217        int stats_valid;
Note: See TracChangeset for help on using the changeset viewer.