this combines errors and qdrops into fails, and shows them by default. if you want to look at drops or errors, you can use d or f to switch to that view.
this also changes netstat so it shows fails by default which is a combination of errors and qdrops too, but -d and -e force drops or errors respectively. it is really frustrating at the moment that i can't see qdrops anywhere, which makes it hard to judge the effectiveness of some changes im working on. for example, this is before and after with netstat: dlg@ix netstat$ netstat -I ix1 Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Colls ix1 1500 <Link> b8:ca:3a:66:e2:72 193968251 0 172754300 0 ix1 1500 192.168.1.3 192.168.1.3 193968251 0 172754300 0 ix1 1500 192.168.1.1 192.168.1.19 193968251 0 172754300 0 dlg@ix netstat$ ./obj/netstat -I ix1 Name Mtu Network Address Ipkts Ifail Opkts Ofail Colls ix1 1500 <Link> b8:ca:3a:66:e2:72 193968251 1789065 172754300 0 ix1 1500 192.168.1.3 192.168.1.3 193968251 1789065 172754300 0 ix1 1500 192.168.1.1 192.168.1.19 193968251 1789065 172754300 0 dlg@ix netstat$ ./obj/netstat -dI ix1 Name Mtu Network Address Ipkts Idrop Opkts Odrop Colls ix1 1500 <Link> b8:ca:3a:66:e2:72 193968251 1789065 172754300 0 ix1 1500 192.168.1.3 192.168.1.3 193968251 1789065 172754300 0 ix1 1500 192.168.1.1 192.168.1.19 193968251 1789065 172754300 0 dlg@ix netstat$ ./obj/netstat -eI ix1 Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Colls ix1 1500 <Link> b8:ca:3a:66:e2:72 193968251 0 172754300 0 ix1 1500 192.168.1.3 192.168.1.3 193968251 0 172754300 0 ix1 1500 192.168.1.1 192.168.1.19 193968251 0 172754300 0 thoughts? Index: systat/if.c =================================================================== RCS file: /cvs/src/usr.bin/systat/if.c,v retrieving revision 1.23 diff -u -p -r1.23 if.c --- systat/if.c 16 Jan 2015 00:03:37 -0000 1.23 +++ systat/if.c 4 Mar 2019 11:13:40 -0000 @@ -56,6 +56,49 @@ static void showifstat(struct ifstat *); static void showtotal(void); static void rt_getaddrinfo(struct sockaddr *, int, struct sockaddr **); +const char ifails[] = "IFAILS"; +const char ofails[] = "OFAILS"; + +#define IF_ERR_SUM 0 +#define IF_ERR_ERRORS 1 +#define IF_ERR_QDROPS 2 + +struct if_err_view { + const char *iname; + const char *oname; + uint64_t (*icount)(const struct ifcount *); + uint64_t (*ocount)(const struct ifcount *); +}; + +static uint64_t if_err_ifails(const struct ifcount *); +static uint64_t if_err_ofails(const struct ifcount *); +static uint64_t if_err_ierrors(const struct ifcount *); +static uint64_t if_err_oerrors(const struct ifcount *); +static uint64_t if_err_iqdrops(const struct ifcount *); +static uint64_t if_err_oqdrops(const struct ifcount *); + +static const struct if_err_view if_err_views[] = { + [IF_ERR_SUM] = { + .iname = ifails, + .oname = ofails, + .icount = if_err_ifails, + .ocount = if_err_ofails, + }, + [IF_ERR_ERRORS] = { + .iname = "IERRS", + .oname = "OERRS", + .icount = if_err_ierrors, + .ocount = if_err_oerrors, + }, + [IF_ERR_QDROPS] = { + .iname = "IQDROPS", + .oname = "OQDROPS", + .icount = if_err_iqdrops, + .ocount = if_err_oqdrops, + }, +}; + +static const struct if_err_view *if_err_view = &if_err_views[IF_ERR_SUM]; /* Define fields */ field_def fields_if[] = { @@ -63,10 +106,10 @@ field_def fields_if[] = { {"STATE", 4, 6, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, {"IPKTS", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, {"IBYTES", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, - {"IERRS", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, + {ifails, 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, {"OPKTS", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, {"OBYTES", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, - {"OERRS", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, + {ofails, 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, {"COLLS", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, {"DESC", 14, 64, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, }; @@ -264,9 +307,11 @@ fetchifstat(void) UPDATE(ifc_ip, ifm_data.ifi_ipackets); UPDATE(ifc_ib, ifm_data.ifi_ibytes); UPDATE(ifc_ie, ifm_data.ifi_ierrors); + UPDATE(ifc_iq, ifm_data.ifi_iqdrops); UPDATE(ifc_op, ifm_data.ifi_opackets); UPDATE(ifc_ob, ifm_data.ifi_obytes); UPDATE(ifc_oe, ifm_data.ifi_oerrors); + UPDATE(ifc_oq, ifm_data.ifi_oqdrops); UPDATE(ifc_co, ifm_data.ifi_collisions); ifs->ifs_cur.ifc_flags = ifm.ifm_flags; ifs->ifs_cur.ifc_state = ifm.ifm_data.ifi_link_state; @@ -315,11 +360,11 @@ showifstat(struct ifstat *ifs) print_fld_sdiv(FLD_IF_IBYTES, ifs->ifs_cur.ifc_ib * conv, div); print_fld_size(FLD_IF_IPKTS, ifs->ifs_cur.ifc_ip); - print_fld_size(FLD_IF_IERRS, ifs->ifs_cur.ifc_ie); + print_fld_size(FLD_IF_IERRS, if_err_view->icount(&ifs->ifs_cur)); print_fld_sdiv(FLD_IF_OBYTES, ifs->ifs_cur.ifc_ob * conv, div); print_fld_size(FLD_IF_OPKTS, ifs->ifs_cur.ifc_op); - print_fld_size(FLD_IF_OERRS, ifs->ifs_cur.ifc_oe); + print_fld_size(FLD_IF_OERRS, if_err_view->ocount(&ifs->ifs_cur)); print_fld_size(FLD_IF_COLLS, ifs->ifs_cur.ifc_co); @@ -336,11 +381,11 @@ showtotal(void) print_fld_sdiv(FLD_IF_IBYTES, sum.ifc_ib * conv, div); print_fld_size(FLD_IF_IPKTS, sum.ifc_ip); - print_fld_size(FLD_IF_IERRS, sum.ifc_ie); + print_fld_size(FLD_IF_IERRS, if_err_view->icount(&sum)); print_fld_sdiv(FLD_IF_OBYTES, sum.ifc_ob * conv, div); print_fld_size(FLD_IF_OPKTS, sum.ifc_op); - print_fld_size(FLD_IF_OERRS, sum.ifc_oe); + print_fld_size(FLD_IF_OERRS, if_err_view->ocount(&sum)); print_fld_size(FLD_IF_COLLS, sum.ifc_co); @@ -348,12 +393,67 @@ showtotal(void) } +static uint64_t +if_err_ifails(const struct ifcount *ifc) +{ + return (ifc->ifc_ie + ifc->ifc_iq); +} + +static uint64_t +if_err_ofails(const struct ifcount *ifc) +{ + return (ifc->ifc_oe + ifc->ifc_oq); +} + +static uint64_t +if_err_ierrors(const struct ifcount *ifc) +{ + return (ifc->ifc_ie); +} + +static uint64_t +if_err_oerrors(const struct ifcount *ifc) +{ + return (ifc->ifc_oe); +} + +static uint64_t +if_err_iqdrops(const struct ifcount *ifc) +{ + return (ifc->ifc_iq); +} + +static uint64_t +if_err_oqdrops(const struct ifcount *ifc) +{ + return (ifc->ifc_oq); +} + +static void +if_set_errs(unsigned int v) +{ + if_err_view = &if_err_views[v]; + FLD_IF_IERRS->title = if_err_view->iname; + FLD_IF_IERRS->title = if_err_view->oname; + gotsig_alarm = 1; +} + int if_keyboard_callback(int ch) { struct ifstat *ifs; switch (ch) { + case 'd': + if_set_errs(IF_ERR_QDROPS); + break; + case 'e': + if_set_errs(IF_ERR_ERRORS); + break; + case 'f': + if_set_errs(IF_ERR_SUM); + break; + case 'r': for (ifs = ifstats; ifs < ifstats + nifs; ifs++) ifs->ifs_old = ifs->ifs_now; Index: systat/systat.1 =================================================================== RCS file: /cvs/src/usr.bin/systat/systat.1,v retrieving revision 1.110 diff -u -p -r1.110 systat.1 --- systat/systat.1 25 Jul 2018 17:24:14 -0000 1.110 +++ systat/systat.1 4 Mar 2019 11:13:40 -0000 @@ -290,6 +290,13 @@ between display refreshes. changes the counters to show the average per second over the display refresh interval; this is the default. +.Ic d +displays input and output queue drops. +.Ic e +displays input and output errors. +.Ic f +displays input and output queue drops plus errors. +This is the default view. .It Ic iostat Display statistics about disk throughput. Statistics Index: systat/systat.h =================================================================== RCS file: /cvs/src/usr.bin/systat/systat.h,v retrieving revision 1.22 diff -u -p -r1.22 systat.h --- systat/systat.h 30 May 2018 13:43:51 -0000 1.22 +++ systat/systat.h 4 Mar 2019 11:13:40 -0000 @@ -104,9 +104,11 @@ struct ifcount { u_int64_t ifc_ib; /* input bytes */ u_int64_t ifc_ip; /* input packets */ u_int64_t ifc_ie; /* input errors */ + u_int64_t ifc_iq; /* input qdrops */ u_int64_t ifc_ob; /* output bytes */ u_int64_t ifc_op; /* output packets */ u_int64_t ifc_oe; /* output errors */ + u_int64_t ifc_oq; /* output qdrops */ u_int64_t ifc_co; /* collisions */ int ifc_flags; /* up / down */ int ifc_state; /* link state */ Index: netstat/if.c =================================================================== RCS file: /cvs/src/usr.bin/netstat/if.c,v retrieving revision 1.74 diff -u -p -r1.74 if.c --- netstat/if.c 5 Oct 2015 15:40:39 -0000 1.74 +++ netstat/if.c 4 Mar 2019 11:13:40 -0000 @@ -63,6 +63,26 @@ static void catchalarm(int); static void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); static void fetchifs(void); +struct iftot; + +struct if_show_err { + const char *name; + const char *iname; + const char *oname; + uint64_t (*count)(uint64_t, uint64_t); +}; + +static uint64_t if_show_fails(uint64_t, uint64_t); +static uint64_t if_show_errors(uint64_t, uint64_t); +static uint64_t if_show_qdrops(uint64_t, uint64_t); + +static const struct if_show_err if_show_errs[] = { + { "fail", "Ifail", "Ofail", if_show_fails }, + { "errs", "Ierrs", "Oerrs", if_show_errors }, + { "drop", "Idrop", "Odrop", if_show_qdrops }, +}; +static const struct if_show_err *if_errs = if_show_errs; + /* * Print a description of the network interfaces. * NOTE: ifnetaddr is the location of the kernel global "ifnet", @@ -83,6 +103,8 @@ intpr(int interval, int repeatcount) u_int64_t total = 0; size_t len; + if_errs = &if_show_errs[dflag]; + if (interval) { sidewaysintpr((unsigned)interval, repeatcount); return; @@ -94,13 +116,13 @@ intpr(int interval, int repeatcount) "Name", "Mtu", "Network", "Address"); if (bflag) printf("%10.10s %10.10s", "Ibytes", "Obytes"); - else + else { printf("%8.8s %5.5s %8.8s %5.5s %5.5s", - "Ipkts", "Ierrs", "Opkts", "Oerrs", "Colls"); + "Ipkts", if_errs->iname, + "Opkts", if_errs->oname, "Colls"); + } if (tflag) printf(" %s", "Time"); - if (dflag) - printf(" %s", "Drop"); putchar('\n'); lim = buf + len; @@ -137,13 +159,15 @@ intpr(int interval, int repeatcount) if (qflag) { total = ifd->ifi_ibytes + ifd->ifi_obytes + - ifd->ifi_ipackets + ifd->ifi_ierrors + - ifd->ifi_opackets + ifd->ifi_oerrors + + ifd->ifi_ipackets + + ifd->ifi_opackets + ifd->ifi_collisions; + total += if_errs->count(ifd->ifi_ierrors, + ifd->ifi_iqdrops); + total += if_errs->count(ifd->ifi_oerrors, + ifd->ifi_oqdrops); if (tflag) total += 0; // XXX ifnet.if_timer; - if (dflag) - total += ifd->ifi_oqdrops; if (total == 0) continue; } @@ -271,13 +295,13 @@ hexprint: ifd->ifi_ibytes, ifd->ifi_obytes); } else printf("%8llu %5llu %8llu %5llu %5llu", - ifd->ifi_ipackets, ifd->ifi_ierrors, - ifd->ifi_opackets, ifd->ifi_oerrors, + ifd->ifi_ipackets, + if_errs->count(ifd->ifi_ierrors, ifd->ifi_iqdrops), + ifd->ifi_opackets, + if_errs->count(ifd->ifi_oerrors, ifd->ifi_oqdrops), ifd->ifi_collisions); if (tflag) printf(" %4d", 0 /* XXX ifnet.if_timer */); - if (dflag) - printf(" %5llu", ifd->ifi_oqdrops); putchar('\n'); } @@ -286,11 +310,12 @@ struct iftot { u_int64_t ift_ip; /* input packets */ u_int64_t ift_ib; /* input bytes */ u_int64_t ift_ie; /* input errors */ + u_int64_t ift_iq; /* input qdrops */ u_int64_t ift_op; /* output packets */ u_int64_t ift_ob; /* output bytes */ u_int64_t ift_oe; /* output errors */ + u_int64_t ift_oq; /* output qdrops */ u_int64_t ift_co; /* collisions */ - u_int64_t ift_dr; /* drops */ } ip_cur, ip_old, sum_cur, sum_old; volatile sig_atomic_t signalled; /* set if alarm goes off "early" */ @@ -328,8 +353,6 @@ banner: printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s", ip_cur.ift_name, " ", ip_cur.ift_name, " ", " "); - if (dflag) - printf(" %5.5s", " "); if (bflag) printf(" %7.7s in %8.8s %6.6s out %5.5s", @@ -337,17 +360,14 @@ banner: else printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s", "total", " ", "total", " ", " "); - if (dflag) - printf(" %5.5s", " "); putchar('\n'); if (bflag) printf("%10.10s %8.8s %10.10s %5.5s", "bytes", " ", "bytes", " "); else printf("%8.8s %5.5s %8.8s %5.5s %5.5s", - "packets", "errs", "packets", "errs", "colls"); - if (dflag) - printf(" %5.5s", "drops"); + "packets", if_errs->name, + "packets", if_errs->name, "colls"); if (bflag) printf("%10.10s %8.8s %10.10s %5.5s", @@ -355,8 +375,6 @@ banner: else printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", "packets", "errs", "packets", "errs", "colls"); - if (dflag) - printf(" %5.5s", "drops"); putchar('\n'); fflush(stdout); line = 0; @@ -380,13 +398,12 @@ loop: } else printf("%8llu %5llu %8llu %5llu %5llu", ip_cur.ift_ip - ip_old.ift_ip, - ip_cur.ift_ie - ip_old.ift_ie, + if_errs->count(ip_cur.ift_ie - ip_old.ift_ie, + ip_cur.ift_iq - ip_old.ift_iq), ip_cur.ift_op - ip_old.ift_op, - ip_cur.ift_oe - ip_old.ift_oe, + if_errs->count(ip_cur.ift_oe - ip_old.ift_oe, + ip_cur.ift_oq - ip_old.ift_oq), ip_cur.ift_co - ip_old.ift_co); - if (dflag) - printf(" %5llu", - ip_cur.ift_dr - ip_old.ift_dr); ip_old = ip_cur; @@ -394,21 +411,21 @@ loop: if (hflag) { fmt_scaled(sum_cur.ift_ib - sum_old.ift_ib, ibytes); fmt_scaled(sum_cur.ift_ob - sum_old.ift_ob, obytes); - printf(" %10s %8.8s %10s %5.5s", + printf("%10s %8.8s %10s %5.5s", ibytes, " ", obytes, " "); } else - printf(" %10llu %8.8s %10llu %5.5s", + printf("%10llu %8.8s %10llu %5.5s", sum_cur.ift_ib - sum_old.ift_ib, " ", sum_cur.ift_ob - sum_old.ift_ob, " "); } else - printf(" %8llu %5llu %8llu %5llu %5llu", + printf("%8llu %5llu %8llu %5llu %5llu", sum_cur.ift_ip - sum_old.ift_ip, - sum_cur.ift_ie - sum_old.ift_ie, + if_errs->count(sum_cur.ift_ie - sum_old.ift_ie, + sum_cur.ift_iq - sum_old.ift_iq), sum_cur.ift_op - sum_old.ift_op, - sum_cur.ift_oe - sum_old.ift_oe, + if_errs->count(sum_cur.ift_oe - sum_old.ift_oe, + sum_cur.ift_oq - sum_old.ift_oq), sum_cur.ift_co - sum_old.ift_co); - if (dflag) - printf(" %5llu", sum_cur.ift_dr - sum_old.ift_dr); sum_old = sum_cur; @@ -547,21 +564,23 @@ fetchifs(void) ip_cur.ift_ip = ifd->ifi_ipackets; ip_cur.ift_ib = ifd->ifi_ibytes; ip_cur.ift_ie = ifd->ifi_ierrors; + ip_cur.ift_iq = ifd->ifi_iqdrops; ip_cur.ift_op = ifd->ifi_opackets; ip_cur.ift_ob = ifd->ifi_obytes; ip_cur.ift_oe = ifd->ifi_oerrors; + ip_cur.ift_oq = ifd->ifi_oqdrops; ip_cur.ift_co = ifd->ifi_collisions; - ip_cur.ift_dr = ifd->ifi_oqdrops; } sum_cur.ift_ip += ifd->ifi_ipackets; sum_cur.ift_ib += ifd->ifi_ibytes; sum_cur.ift_ie += ifd->ifi_ierrors; + sum_cur.ift_iq += ifd->ifi_iqdrops; sum_cur.ift_op += ifd->ifi_opackets; sum_cur.ift_ob += ifd->ifi_obytes; sum_cur.ift_oe += ifd->ifi_oerrors; + sum_cur.ift_oq += ifd->ifi_oqdrops; sum_cur.ift_co += ifd->ifi_collisions; - sum_cur.ift_dr += ifd->ifi_oqdrops; break; } } @@ -571,11 +590,30 @@ fetchifs(void) ip_cur.ift_ip = ifd->ifi_ipackets; ip_cur.ift_ib = ifd->ifi_ibytes; ip_cur.ift_ie = ifd->ifi_ierrors; + ip_cur.ift_iq = ifd->ifi_iqdrops; ip_cur.ift_op = ifd->ifi_opackets; ip_cur.ift_ob = ifd->ifi_obytes; ip_cur.ift_oe = ifd->ifi_oerrors; + ip_cur.ift_oq = ifd->ifi_oqdrops; ip_cur.ift_co = ifd->ifi_collisions; - ip_cur.ift_dr = ifd->ifi_oqdrops; } free(buf); +} + +static uint64_t +if_show_fails(uint64_t errors, uint64_t qdrops) +{ + return (errors + qdrops); +} + +static uint64_t +if_show_errors(uint64_t errors, uint64_t qdrops) +{ + return (errors); +} + +static uint64_t +if_show_qdrops(uint64_t errors, uint64_t qdrops) +{ + return (qdrops); } Index: netstat/main.c =================================================================== RCS file: /cvs/src/usr.bin/netstat/main.c,v retrieving revision 1.113 diff -u -p -r1.113 main.c --- netstat/main.c 13 Aug 2018 14:36:54 -0000 1.113 +++ netstat/main.c 4 Mar 2019 11:13:40 -0000 @@ -129,7 +129,7 @@ main(int argc, char *argv[]) tableid = getrtable(); while ((ch = getopt(argc, argv, - "AaBbc:dFf:ghI:iLlM:mN:np:P:qrsT:tuvW:w:")) != -1) + "AaBbc:deFf:ghI:iLlM:mN:np:P:qrsT:tuvW:w:")) != -1) switch (ch) { case 'A': Aflag = 1; @@ -149,7 +149,10 @@ main(int argc, char *argv[]) errx(1, "count is %s", errstr); break; case 'd': - dflag = 1; + dflag = IF_SHOW_DROP; + break; + case 'e': + dflag = IF_SHOW_ERRS; break; case 'F': Fflag = 1; Index: netstat/netstat.1 =================================================================== RCS file: /cvs/src/usr.bin/netstat/netstat.1,v retrieving revision 1.83 diff -u -p -r1.83 netstat.1 --- netstat/netstat.1 13 Jul 2018 09:06:58 -0000 1.83 +++ netstat/netstat.1 4 Mar 2019 11:13:40 -0000 @@ -45,7 +45,7 @@ .Op Fl N Ar system .Nm netstat .Bk -words -.Op Fl bdFgilmnqrstu +.Op Fl bdeFgilmnqrstu .Op Fl f Ar address_family .Op Fl p Ar protocol .Op Fl M Ar core @@ -53,7 +53,7 @@ .Op Fl T Ar rtable .Ek .Nm netstat -.Op Fl bdhn +.Op Fl bdehn .Op Fl c Ar count .Op Fl I Ar interface .Op Fl M Ar core Index: netstat/netstat.h =================================================================== RCS file: /cvs/src/usr.bin/netstat/netstat.h,v retrieving revision 1.72 diff -u -p -r1.72 netstat.h --- netstat/netstat.h 13 Aug 2018 14:36:54 -0000 1.72 +++ netstat/netstat.h 4 Mar 2019 11:13:40 -0000 @@ -142,6 +142,10 @@ void routepr(u_long, u_long, u_long, u_l void nsprotopr(u_long, char *); +#define IF_SHOW_FAIL 0 +#define IF_SHOW_ERRS 1 +#define IF_SHOW_DROP 2 + void intpr(int, int); void mroutepr(void);