Hi tech@, currently, the PF states view in systat(1) cannot be sorted by average rate. The following patch adds this functionality by storing the average in the cache struct instead of calculating it during printing.
Regards Lukas Index: cache.c =================================================================== RCS file: /cvs/src/usr.bin/systat/cache.c,v retrieving revision 1.7 diff -u -p -u -p -r1.7 cache.c --- cache.c 26 Aug 2016 09:10:11 -0000 1.7 +++ cache.c 5 Jun 2018 17:11:35 -0000 @@ -98,6 +98,8 @@ update_state(struct sc_ent *prev, struct prev->t = time(NULL); prev->rate = rate; prev->bytes = COUNTER(new->bytes[0]) + COUNTER(new->bytes[1]); + prev->avg = (new->creation) ? + ((double)prev->bytes / (double)ntohl(new->creation)) : -1; if (prev->peak < rate) prev->peak = rate; } @@ -124,6 +126,7 @@ add_state(struct pfsync_state *st) ent->bytes = COUNTER(st->bytes[0]) + COUNTER(st->bytes[1]); ent->peak = 0; ent->rate = 0; + ent->avg = 0; ent->t = 0; RB_INSERT(sc_tree, &sctree, ent); Index: cache.h =================================================================== RCS file: /cvs/src/usr.bin/systat/cache.h,v retrieving revision 1.5 diff -u -p -u -p -r1.5 cache.h --- cache.h 16 Jan 2016 03:30:26 -0000 1.5 +++ cache.h 5 Jun 2018 17:11:35 -0000 @@ -29,6 +29,7 @@ struct sc_ent { u_int32_t creatorid; double peak; double rate; + double avg; time_t t; u_int64_t bytes; }; Index: pftop.c =================================================================== RCS file: /cvs/src/usr.bin/systat/pftop.c,v retrieving revision 1.41 diff -u -p -u -p -r1.41 pftop.c --- pftop.c 8 Feb 2018 07:00:33 -0000 1.41 +++ pftop.c 5 Jun 2018 17:11:35 -0000 @@ -103,6 +103,7 @@ int sort_da_callback(const void *s1, con int sort_dp_callback(const void *s1, const void *s2); int sort_rate_callback(const void *s1, const void *s2); int sort_peak_callback(const void *s1, const void *s2); +int sort_avg_callback(const void *s1, const void *s2); int pf_dev = -1; struct sc_ent **state_cache = NULL; @@ -263,6 +264,7 @@ order_type order_list[] = { {"dest. port", "dport", 'D', sort_dp_callback}, {"rate", "rate", 'R', sort_rate_callback}, {"peak", "peak", 'K', sort_peak_callback}, + {"avg", "avg", 'V', sort_avg_callback}, {NULL, NULL, 0, NULL} }; @@ -379,6 +381,24 @@ sort_rate_callback(const void *s1, const } int +sort_avg_callback(const void *s1, const void *s2) +{ + struct sc_ent *e1 = state_cache[* (u_int32_t *) s1]; + struct sc_ent *e2 = state_cache[* (u_int32_t *) s2]; + + if (e2 == NULL) + return -sortdir; + if (e1 == NULL || e2 == NULL) + return 0; + + if (e2->avg > e1->avg) + return sortdir; + if (e2->avg < e1->avg) + return -sortdir; + return 0; +} + +int sort_peak_callback(const void *s1, const void *s2) { struct sc_ent *e1 = state_cache[* (u_int32_t *) s1]; @@ -884,13 +904,12 @@ print_state(struct pfsync_state * s, str print_fld_size(FLD_PKTS, COUNTER(s->packets[0]) + COUNTER(s->packets[1])); print_fld_size(FLD_BYTES, sz); - print_fld_rate(FLD_SA, (s->creation) ? - ((double)sz/(double)ntohl(s->creation)) : -1); print_fld_uint(FLD_RULE, ntohl(s->rule)); if (cachestates && ent != NULL) { print_fld_rate(FLD_SI, ent->rate); print_fld_rate(FLD_SP, ent->peak); + print_fld_rate(FLD_SA, ent->avg); } end_line(); @@ -1708,10 +1727,12 @@ update_cache(void) if (cachestates) { show_field(FLD_SI); show_field(FLD_SP); + show_field(FLD_SA); gotsig_alarm = 1; } else { hide_field(FLD_SI); hide_field(FLD_SP); + hide_field(FLD_SA); need_update = 1; } field_setup(); Index: systat.1 =================================================================== RCS file: /cvs/src/usr.bin/systat/systat.1,v retrieving revision 1.106 diff -u -p -u -p -r1.106 systat.1 --- systat.1 30 May 2018 13:53:09 -0000 1.106 +++ systat.1 5 Jun 2018 17:11:35 -0000 @@ -413,8 +413,9 @@ Available orderings are: .Ic destination address , .Ic destination port , .Ic rate , +.Ic peak , and -.Ic peak +.Ic average columns. .It Ic swap Show information about swap space usage on all the