[BACK]Return to pftop.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / systat

Diff for /src/usr.bin/systat/pftop.c between version 1.23 and 1.24

version 1.23, 2014/02/11 01:07:21 version 1.24, 2014/04/18 11:36:06
Line 41 
Line 41 
 #include <net/pfvar.h>  #include <net/pfvar.h>
 #include <arpa/inet.h>  #include <arpa/inet.h>
   
 #include <altq/altq.h>  
 #include <altq/altq_cbq.h>  
 #include <altq/altq_priq.h>  
 #include <altq/altq_hfsc.h>  
   
 #include <net/hfsc.h>  #include <net/hfsc.h>
   
 #include <ctype.h>  #include <ctype.h>
Line 117 
Line 112 
 u_int32_t num_states_all = 0;  u_int32_t num_states_all = 0;
 u_int32_t num_rules = 0;  u_int32_t num_rules = 0;
 u_int32_t num_queues = 0;  u_int32_t num_queues = 0;
 u_int32_t num_altqs = 0;  
 int cachestates = 0;  int cachestates = 0;
   
 char *filter_string = NULL;  char *filter_string = NULL;
Line 297 
Line 291 
         {NULL, NULL, 0, NULL}          {NULL, NULL, 0, NULL}
 };  };
   
   
 /* altq structures from pfctl */  
   
 union class_stats {  
         class_stats_t           cbq_stats;  
         struct priq_classstats  priq_stats;  
         struct hfsc_classstats  hfsc_stats;  
 };  
   
 struct altq_stats {  
         union class_stats        data;  
         struct timeval           timestamp;  
         u_int8_t                 valid;  
 };  
   
 struct pf_altq_node {  
         struct pf_altq           altq;  
         struct pf_altq_node     *next;  
         struct pf_altq_node     *children;  
         struct pf_altq_node     *next_flat;  
         struct altq_stats        qstats;  
         struct altq_stats        qstats_last;  
         u_int8_t                 depth;  
         u_int8_t                 visited;  
 };  
   
 /* queue structures from pfctl */  /* queue structures from pfctl */
   
 struct queue_stats {  struct queue_stats {
Line 1511 
Line 1479 
 }  }
   
 /* queue display */  /* queue display */
   
 struct pf_altq_node *  
 pfctl_find_altq_node(struct pf_altq_node *root, const char *qname,  
     const char *ifname)  
 {  
         struct pf_altq_node     *node, *child;  
   
         for (node = root; node != NULL; node = node->next) {  
                 if (!strcmp(node->altq.qname, qname)  
                     && !(strcmp(node->altq.ifname, ifname)))  
                         return (node);  
                 if (node->children != NULL) {  
                         child = pfctl_find_altq_node(node->children, qname,  
                             ifname);  
                         if (child != NULL)  
                                 return (child);  
                 }  
         }  
         return (NULL);  
 }  
   
 void  
 pfctl_insert_altq_node(struct pf_altq_node **root,  
     const struct pf_altq altq, const struct altq_stats qstats)  
 {  
         struct pf_altq_node     *node;  
   
         node = calloc(1, sizeof(struct pf_altq_node));  
         if (node == NULL)  
                 err(1, "pfctl_insert_altq_node: calloc");  
         memcpy(&node->altq, &altq, sizeof(struct pf_altq));  
         memcpy(&node->qstats, &qstats, sizeof(qstats));  
         node->next = node->children = node->next_flat = NULL;  
         node->depth = 0;  
         node->visited = 1;  
   
         if (*root == NULL)  
                 *root = node;  
         else if (!altq.parent[0]) {  
                 struct pf_altq_node     *prev = *root;  
   
                 while (prev->next != NULL)  
                         prev = prev->next;  
                 prev->next = node;  
         } else {  
                 struct pf_altq_node     *parent;  
   
                 parent = pfctl_find_altq_node(*root, altq.parent, altq.ifname);  
                 if (parent == NULL)  
                         errx(1, "parent %s not found", altq.parent);  
                 node->depth = parent->depth+1;  
                 if (parent->children == NULL)  
                         parent->children = node;  
                 else {  
                         struct pf_altq_node *prev = parent->children;  
   
                         while (prev->next != NULL)  
                                 prev = prev->next;  
                         prev->next = node;  
                 }  
         }  
 }  
   
 void  
 pfctl_set_next_flat(struct pf_altq_node *node, struct pf_altq_node *up)  
 {  
         while (node) {  
                 struct pf_altq_node *next = node->next ? node->next : up;  
                 if (node->children) {  
                         node->next_flat = node->children;  
                         pfctl_set_next_flat(node->children, next);  
                 } else  
                         node->next_flat = next;  
                 node = node->next;  
         }  
 }  
   
 struct pfctl_queue_node *  struct pfctl_queue_node *
 pfctl_find_queue_node(const char *qname, const char *ifname)  pfctl_find_queue_node(const char *qname, const char *ifname)
 {  {
Line 1683 
Line 1574 
 }  }
   
 int  int
 pfctl_update_altqstats(struct pf_altq_node **root, int *inserts)  
 {  
         struct pf_altq_node     *node;  
         struct pfioc_altq        pa;  
         struct pfioc_altqstats   pq;  
         u_int32_t                nr;  
         struct altq_stats        qstats;  
         u_int32_t                nr_queues;  
         int                      ret = 0;  
   
         *inserts = 0;  
         memset(&pa, 0, sizeof(pa));  
         memset(&pq, 0, sizeof(pq));  
         memset(&qstats, 0, sizeof(qstats));  
   
         if (pf_dev < 0)  
                 return (-1);  
   
         if (ioctl(pf_dev, DIOCGETALTQS, &pa)) {  
                 error("DIOCGETALTQS: %s", strerror(errno));  
                 return (-1);  
         }  
   
         num_altqs = nr_queues = pa.nr;  
         for (nr = 0; nr < nr_queues; ++nr) {  
                 pa.nr = nr;  
                 if (ioctl(pf_dev, DIOCGETALTQ, &pa)) {  
                         error("DIOCGETALTQ: %s", strerror(errno));  
                         ret = -1;  
                         break;  
                 }  
                 if (pa.altq.qid > 0) {  
                         pq.nr = nr;  
                         pq.ticket = pa.ticket;  
                         pq.buf = &qstats;  
                         pq.nbytes = sizeof(qstats);  
                         if (ioctl(pf_dev, DIOCGETALTQSTATS, &pq)) {  
                                 error("DIOCGETALTQSTATS: %s", strerror(errno));  
                                 ret = -1;  
                                 break;  
                         }  
                         qstats.valid = 1;  
                         gettimeofday(&qstats.timestamp, NULL);  
                         if ((node = pfctl_find_altq_node(*root, pa.altq.qname,  
                             pa.altq.ifname)) != NULL) {  
                                 /* update altq data too as bandwidth may have changed */  
                                 memcpy(&node->altq, &pa.altq, sizeof(struct pf_altq));  
                                 memcpy(&node->qstats_last, &node->qstats,  
                                     sizeof(struct altq_stats));  
                                 memcpy(&node->qstats, &qstats,  
                                     sizeof(qstats));  
                                 node->visited = 1;  
                         } else {  
                                 pfctl_insert_altq_node(root, pa.altq, qstats);  
                                 *inserts = 1;  
                         }  
                 }  
                 else  
                         --num_altqs;  
         }  
   
         pfctl_set_next_flat(*root, NULL);  
   
         return (ret);  
 }  
   
 void  
 pfctl_free_altq_node(struct pf_altq_node *node)  
 {  
         while (node != NULL) {  
                 struct pf_altq_node     *prev;  
   
                 if (node->children != NULL)  
                         pfctl_free_altq_node(node->children);  
                 prev = node;  
                 node = node->next;  
                 free(prev);  
         }  
 }  
   
 void  
 pfctl_mark_all_unvisited(struct pf_altq_node *root)  
 {  
         if (root != NULL) {  
                 struct pf_altq_node     *node = root;  
                 while (node != NULL) {  
                         node->visited = 0;  
                         node = node->next_flat;  
                 }  
         }  
 }  
   
 int  
 pfctl_have_unvisited(struct pf_altq_node *root)  
 {  
         if (root == NULL)  
                 return(0);  
         else {  
                 struct pf_altq_node     *node = root;  
                 while (node != NULL) {  
                         if (node->visited == 0)  
                                 return(1);  
                         node = node->next_flat;  
                 }  
                 return(0);  
         }  
 }  
   
 struct pf_altq_node     *altq_root = NULL;  
   
 int  
 select_queues(void)  select_queues(void)
 {  {
         num_disp = num_queues + num_altqs;          num_disp = num_queues;
         return (0);          return (0);
 }  }
   
Line 1806 
Line 1586 
         static int first_read = 1;          static int first_read = 1;
         struct pfctl_queue_node *node;          struct pfctl_queue_node *node;
         int inserts;          int inserts;
         num_disp = num_altqs = num_queues = 0;          num_disp = num_queues = 0;
   
         pfctl_mark_all_unvisited(altq_root);  
         if (pfctl_update_altqstats(&altq_root, &inserts))  
                 return (-1);  
   
         while ((node = TAILQ_FIRST(&qnodes)) != NULL) {          while ((node = TAILQ_FIRST(&qnodes)) != NULL) {
                 TAILQ_REMOVE(&qnodes, node, entries);                  TAILQ_REMOVE(&qnodes, node, entries);
                 free(node);                  free(node);
         }          }
         if (pfctl_update_qstats() < 0)          if (pfctl_update_qstats() < 0)
                 return (-1);                  return (-1);
           num_disp = num_queues;
   
         /* Allow inserts only on first read;  
          * on subsequent reads clear and reload  
          */  
         if (first_read == 0 &&  
             (inserts != 0 || pfctl_have_unvisited(altq_root) != 0)) {  
                 pfctl_free_altq_node(altq_root);  
                 altq_root = NULL;  
                 first_read = 1;  
                 if (pfctl_update_altqstats(&altq_root, &inserts))  
                         return (-1);  
         }  
   
         first_read = 0;  
         num_disp = num_queues + num_altqs;  
   
         return(0);          return(0);
 }  }
   
Line 1866 
Line 1628 
         return (pps);          return (pps);
 }  }
   
 #define DEFAULT_PRIORITY        1  
   
 void  void
 print_altqueue(struct pf_altq_node *node)  
 {  
         u_int8_t d;  
         double  interval, pps, bps;  
         pps = bps = 0;  
   
         tb_start();  
         for (d = 0; d < node->depth; d++)  
                 tbprintf(" ");  
         tbprintf(node->altq.qname);  
         print_fld_tb(FLD_QUEUE);  
   
         if (node->altq.scheduler == ALTQT_CBQ ||  
             node->altq.scheduler == ALTQT_HFSC  
                 )  
                 print_fld_bw(FLD_BANDW, (double)node->altq.bandwidth);  
   
         if (node->altq.priority != DEFAULT_PRIORITY)  
                 print_fld_uint(FLD_PRIO,  
                                node->altq.priority);  
   
         if (node->qstats.valid && node->qstats_last.valid)  
                 interval = calc_interval(&node->qstats.timestamp,  
                                          &node->qstats_last.timestamp);  
         else  
                 interval = 0;  
   
         switch (node->altq.scheduler) {  
         case ALTQT_CBQ:  
                 print_fld_str(FLD_SCHED, "cbq");  
                 print_fld_size(FLD_PKTS,  
                                node->qstats.data.cbq_stats.xmit_cnt.packets);  
                 print_fld_size(FLD_BYTES,  
                                node->qstats.data.cbq_stats.xmit_cnt.bytes);  
                 print_fld_size(FLD_DROPP,  
                                node->qstats.data.cbq_stats.drop_cnt.packets);  
                 print_fld_size(FLD_DROPB,  
                                node->qstats.data.cbq_stats.drop_cnt.bytes);  
                 print_fld_size(FLD_QLEN, node->qstats.data.cbq_stats.qcnt);  
                 print_fld_size(FLD_BORR, node->qstats.data.cbq_stats.borrows);  
                 print_fld_size(FLD_SUSP, node->qstats.data.cbq_stats.delays);  
                 if (interval > 0) {  
                         pps = calc_pps(node->qstats.data.cbq_stats.xmit_cnt.packets,  
                                        node->qstats_last.data.cbq_stats.xmit_cnt.packets, interval);  
                         bps = calc_rate(node->qstats.data.cbq_stats.xmit_cnt.bytes,  
                                         node->qstats_last.data.cbq_stats.xmit_cnt.bytes, interval);  
                 }  
                 break;  
         case ALTQT_PRIQ:  
                 print_fld_str(FLD_SCHED, "priq");  
                 print_fld_size(FLD_PKTS,  
                                node->qstats.data.priq_stats.xmitcnt.packets);  
                 print_fld_size(FLD_BYTES,  
                                node->qstats.data.priq_stats.xmitcnt.bytes);  
                 print_fld_size(FLD_DROPP,  
                                node->qstats.data.priq_stats.dropcnt.packets);  
                 print_fld_size(FLD_DROPB,  
                                node->qstats.data.priq_stats.dropcnt.bytes);  
                 print_fld_size(FLD_QLEN, node->qstats.data.priq_stats.qlength);  
                 if (interval > 0) {  
                         pps = calc_pps(node->qstats.data.priq_stats.xmitcnt.packets,  
                                        node->qstats_last.data.priq_stats.xmitcnt.packets, interval);  
                         bps = calc_rate(node->qstats.data.priq_stats.xmitcnt.bytes,  
                                         node->qstats_last.data.priq_stats.xmitcnt.bytes, interval);  
                 }  
                 break;  
         case ALTQT_HFSC:  
                 print_fld_str(FLD_SCHED, "hfsc");  
                 print_fld_size(FLD_PKTS,  
                                 node->qstats.data.hfsc_stats.xmit_cnt.packets);  
                 print_fld_size(FLD_BYTES,  
                                 node->qstats.data.hfsc_stats.xmit_cnt.bytes);  
                 print_fld_size(FLD_DROPP,  
                                 node->qstats.data.hfsc_stats.drop_cnt.packets);  
                 print_fld_size(FLD_DROPB,  
                                 node->qstats.data.hfsc_stats.drop_cnt.bytes);  
                 print_fld_size(FLD_QLEN, node->qstats.data.hfsc_stats.qlength);  
                 if (interval > 0) {  
                         pps = calc_pps(node->qstats.data.hfsc_stats.xmit_cnt.packets,  
                                         node->qstats_last.data.hfsc_stats.xmit_cnt.packets, interval);  
                         bps = calc_rate(node->qstats.data.hfsc_stats.xmit_cnt.bytes,  
                                         node->qstats_last.data.hfsc_stats.xmit_cnt.bytes, interval);  
                 }  
                 break;  
         }  
   
         /* if (node->altq.scheduler != ALTQT_HFSC && interval > 0) { */  
         if (node->altq.scheduler && interval > 0) {  
                 tb_start();  
                 if (pps > 0 && pps < 1)  
                         tbprintf("%-3.1lf", pps);  
                 else  
                         tbprintf("%u", (unsigned int) pps);  
   
                 print_fld_tb(FLD_PKTSPS);  
                 print_fld_bw(FLD_BYTESPS, bps);  
         }  
 }  
   
 void  
 print_queue_node(struct pfctl_queue_node *node)  print_queue_node(struct pfctl_queue_node *node)
 {  {
         u_int   rate;          u_int   rate;
Line 2023 
Line 1683 
 print_queues(void)  print_queues(void)
 {  {
         uint32_t n, count, start;          uint32_t n, count, start;
         struct pf_altq_node *altqnode = altq_root;  
         struct pfctl_queue_node *node;          struct pfctl_queue_node *node;
   
         n = count = 0;          n = count = 0;
Line 2039 
Line 1698 
                 count++;                  count++;
                 if (maxprint > 0 && count >= maxprint)                  if (maxprint > 0 && count >= maxprint)
                         return;                          return;
         }  
   
         start -= n;  
         for (n = 0; n < start; n++)  
                 altqnode = altqnode->next_flat;  
   
         for (; n < num_altqs; n++) {  
                 print_altqueue(altqnode);  
                 altqnode = altqnode->next_flat;  
                 end_line();  
                 count++;  
                 if (maxprint > 0 && count >= maxprint)  
                         break;  
         }          }
 }  }
   

Legend:
Removed from v.1.23  
changed lines
  Added in v.1.24