[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.21 and 1.22

version 1.21, 2013/10/12 12:17:32 version 1.22, 2014/01/19 23:45:34
Line 46 
Line 46 
 #include <altq/altq_priq.h>  #include <altq/altq_priq.h>
 #include <altq/altq_hfsc.h>  #include <altq/altq_hfsc.h>
   
   #include <net/hfsc.h>
   
 #include <ctype.h>  #include <ctype.h>
 #include <curses.h>  #include <curses.h>
 #include <err.h>  #include <err.h>
Line 115 
Line 117 
 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 303 
Line 306 
         struct hfsc_classstats  hfsc_stats;          struct hfsc_classstats  hfsc_stats;
 };  };
   
 struct queue_stats {  struct altq_stats {
         union class_stats        data;          union class_stats        data;
         struct timeval           timestamp;          struct timeval           timestamp;
         u_int8_t                 valid;          u_int8_t                 valid;
Line 314 
Line 317 
         struct pf_altq_node     *next;          struct pf_altq_node     *next;
         struct pf_altq_node     *children;          struct pf_altq_node     *children;
         struct pf_altq_node     *next_flat;          struct pf_altq_node     *next_flat;
         struct queue_stats       qstats;          struct altq_stats        qstats;
         struct queue_stats       qstats_last;          struct altq_stats        qstats_last;
         u_int8_t                 depth;          u_int8_t                 depth;
         u_int8_t                 visited;          u_int8_t                 visited;
 };  };
   
   /* queue structures from pfctl */
   
   struct queue_stats {
           struct hfsc_class_stats  data;
           int                      valid;
           struct timeval           timestamp;
   };
   
   struct pfctl_queue_node {
           TAILQ_ENTRY(pfctl_queue_node)   entries;
           struct pf_queuespec             qs;
           struct queue_stats              qstats;
           struct queue_stats              qstats_last;
           int                             depth;
   };
   TAILQ_HEAD(qnodes, pfctl_queue_node) qnodes = TAILQ_HEAD_INITIALIZER(qnodes);
   
 /* ordering functions */  /* ordering functions */
   
 int  int
Line 1515 
Line 1534 
   
 void  void
 pfctl_insert_altq_node(struct pf_altq_node **root,  pfctl_insert_altq_node(struct pf_altq_node **root,
     const struct pf_altq altq, const struct queue_stats qstats)      const struct pf_altq altq, const struct altq_stats qstats)
 {  {
         struct pf_altq_node     *node;          struct pf_altq_node     *node;
   
Line 1569 
Line 1588 
         }          }
 }  }
   
   struct pfctl_queue_node *
   pfctl_find_queue_node(const char *qname, const char *ifname)
   {
           struct pfctl_queue_node *node;
   
           TAILQ_FOREACH(node, &qnodes, entries)
                   if (!strcmp(node->qs.qname, qname)
                       && !(strcmp(node->qs.ifname, ifname)))
                           return (node);
           return (NULL);
   }
   
   void
   pfctl_insert_queue_node(const struct pf_queuespec qs,
       const struct queue_stats qstats)
   {
           struct pfctl_queue_node *node, *parent;
   
           node = calloc(1, sizeof(struct pfctl_queue_node));
           if (node == NULL)
                   err(1, "pfctl_insert_queue_node: calloc");
           memcpy(&node->qs, &qs, sizeof(qs));
           memcpy(&node->qstats, &qstats, sizeof(qstats));
   
           if (node->qs.parent[0]) {
                   parent = pfctl_find_queue_node(node->qs.parent,
                       node->qs.ifname);
                   if (parent)
                           node->depth = parent->depth + 1;
           }
   
           TAILQ_INSERT_TAIL(&qnodes, node, entries);
   }
   
 int  int
 pfctl_update_qstats(struct pf_altq_node **root, int *inserts)  pfctl_update_qstats(void)
 {  {
           struct pfctl_queue_node *node;
           struct pfioc_queue       pq;
           struct pfioc_qstats      pqs;
           u_int32_t                mnr, nr;
           struct queue_stats       qstats;
           static u_int32_t         last_ticket;
   
           memset(&pq, 0, sizeof(pq));
           memset(&pqs, 0, sizeof(pqs));
           memset(&qstats, 0, sizeof(qstats));
   
           if (pf_dev < 0)
                   return (-1);
   
           if (ioctl(pf_dev, DIOCGETQUEUES, &pq)) {
                   error("DIOCGETQUEUES: %s", strerror(errno));
                   return (-1);
           }
   
           /* if a new set is found, start over */
           if (pq.ticket != last_ticket)
                   while ((node = TAILQ_FIRST(&qnodes)) != NULL)
                           TAILQ_REMOVE(&qnodes, node, entries);
           last_ticket = pq.ticket;
   
           num_queues = mnr = pq.nr;
           for (nr = 0; nr < mnr; ++nr) {
                   pqs.nr = nr;
                   pqs.ticket = pq.ticket;
                   pqs.buf = &qstats.data;
                   pqs.nbytes = sizeof(qstats.data);
                   if (ioctl(pf_dev, DIOCGETQSTATS, &pqs)) {
                           error("DIOCGETQSTATS: %s", strerror(errno));
                           return (-1);
                   }
                   if (pqs.queue.qname[0] != '_') {
                           if (pqs.queue.parent[0] && pqs.queue.parent[0] == '_')
                                   pqs.queue.parent[0] = '\0';
                           qstats.valid = 1;
                           gettimeofday(&qstats.timestamp, NULL);
                           if ((node = pfctl_find_queue_node(pqs.queue.qname,
                               pqs.queue.ifname)) != NULL) {
                                   memcpy(&node->qstats_last, &node->qstats,
                                       sizeof(struct queue_stats));
                                   memcpy(&node->qstats, &qstats,
                                       sizeof(struct queue_stats));
                           } else {
                                   pfctl_insert_queue_node(pqs.queue, qstats);
                           }
                   } else
                           num_queues--;
           }
           return (0);
   }
   
   int
   pfctl_update_altqstats(struct pf_altq_node **root, int *inserts)
   {
         struct pf_altq_node     *node;          struct pf_altq_node     *node;
         struct pfioc_altq        pa;          struct pfioc_altq        pa;
         struct pfioc_altqstats   pq;          struct pfioc_altqstats   pq;
         u_int32_t                nr;          u_int32_t                nr;
         struct queue_stats       qstats;          struct altq_stats        qstats;
         u_int32_t                nr_queues;          u_int32_t                nr_queues;
         int                      ret = 0;          int                      ret = 0;
   
Line 1593 
Line 1704 
                 return (-1);                  return (-1);
         }          }
   
         num_queues = nr_queues = pa.nr;          num_altqs = nr_queues = pa.nr;
         for (nr = 0; nr < nr_queues; ++nr) {          for (nr = 0; nr < nr_queues; ++nr) {
                 pa.nr = nr;                  pa.nr = nr;
                 if (ioctl(pf_dev, DIOCGETALTQ, &pa)) {                  if (ioctl(pf_dev, DIOCGETALTQ, &pa)) {
Line 1606 
Line 1717 
                         pq.ticket = pa.ticket;                          pq.ticket = pa.ticket;
                         pq.buf = &qstats;                          pq.buf = &qstats;
                         pq.nbytes = sizeof(qstats);                          pq.nbytes = sizeof(qstats);
                         if (ioctl(pf_dev, DIOCGETQSTATS, &pq)) {                          if (ioctl(pf_dev, DIOCGETALTQSTATS, &pq)) {
                                 error("DIOCGETQSTATS: %s", strerror(errno));                                  error("DIOCGETALTQSTATS: %s", strerror(errno));
                                 ret = -1;                                  ret = -1;
                                 break;                                  break;
                         }                          }
Line 1618 
Line 1729 
                                 /* update altq data too as bandwidth may have changed */                                  /* update altq data too as bandwidth may have changed */
                                 memcpy(&node->altq, &pa.altq, sizeof(struct pf_altq));                                  memcpy(&node->altq, &pa.altq, sizeof(struct pf_altq));
                                 memcpy(&node->qstats_last, &node->qstats,                                  memcpy(&node->qstats_last, &node->qstats,
                                     sizeof(struct queue_stats));                                      sizeof(struct altq_stats));
                                 memcpy(&node->qstats, &qstats,                                  memcpy(&node->qstats, &qstats,
                                     sizeof(qstats));                                      sizeof(qstats));
                                 node->visited = 1;                                  node->visited = 1;
Line 1628 
Line 1739 
                         }                          }
                 }                  }
                 else                  else
                         --num_queues;                          --num_altqs;
         }          }
   
         pfctl_set_next_flat(*root, NULL);          pfctl_set_next_flat(*root, NULL);
Line 1683 
Line 1794 
 int  int
 select_queues(void)  select_queues(void)
 {  {
         num_disp = num_queues;          num_disp = num_queues + num_altqs;
         return (0);          return (0);
 }  }
   
Line 1691 
Line 1802 
 read_queues(void)  read_queues(void)
 {  {
         static int first_read = 1;          static int first_read = 1;
           struct pfctl_queue_node *node;
         int inserts;          int inserts;
         num_disp = num_queues = 0;          num_disp = num_altqs = num_queues = 0;
   
         pfctl_mark_all_unvisited(altq_root);          pfctl_mark_all_unvisited(altq_root);
         if (pfctl_update_qstats(&altq_root, &inserts))          if (pfctl_update_altqstats(&altq_root, &inserts))
                 return (-1);                  return (-1);
   
           while ((node = TAILQ_FIRST(&qnodes)) != NULL)
                   TAILQ_REMOVE(&qnodes, node, entries);
           if (pfctl_update_qstats() < 0)
                   return (-1);
   
         /* Allow inserts only on first read;          /* Allow inserts only on first read;
          * on subsequent reads clear and reload           * on subsequent reads clear and reload
Line 1706 
Line 1823 
                 pfctl_free_altq_node(altq_root);                  pfctl_free_altq_node(altq_root);
                 altq_root = NULL;                  altq_root = NULL;
                 first_read = 1;                  first_read = 1;
                 if (pfctl_update_qstats(&altq_root, &inserts))                  if (pfctl_update_altqstats(&altq_root, &inserts))
                         return (-1);                          return (-1);
         }          }
   
         first_read = 0;          first_read = 0;
         num_disp = num_queues;          num_disp = num_queues + num_altqs;
   
         return(0);          return(0);
 }  }
Line 1748 
Line 1865 
 #define DEFAULT_PRIORITY        1  #define DEFAULT_PRIORITY        1
   
 void  void
 print_queue(struct pf_altq_node *node)  print_altqueue(struct pf_altq_node *node)
 {  {
         u_int8_t d;          u_int8_t d;
         double  interval, pps, bps;          double  interval, pps, bps;
Line 1848 
Line 1965 
 }  }
   
 void  void
   print_queue_node(struct pfctl_queue_node *node)
   {
           u_int   rate;
           int     i;
           double  interval, pps, bps;
           static const char unit[] = " KMG";
   
           tb_start();
           for (i = 0; i < node->depth; i++)
                   tbprintf(" ");
           tbprintf("%s", node->qs.qname);
           print_fld_tb(FLD_QUEUE);
   
           // XXX: missing min, max, burst
           tb_start();
           rate = node->qs.linkshare.m2.absolute;
           for (i = 0; rate >= 1000 && i <= 3; i++)
                   rate /= 1000;
           tbprintf("%u%c", rate, unit[i]);
           print_fld_tb(FLD_BANDW);
   
           if (node->qstats.valid && node->qstats_last.valid)
                   interval = calc_interval(&node->qstats.timestamp,
                       &node->qstats_last.timestamp);
           else
                   interval = 0;
   
           print_fld_size(FLD_PKTS, node->qstats.data.xmit_cnt.packets);
           print_fld_size(FLD_BYTES, node->qstats.data.xmit_cnt.bytes);
           print_fld_size(FLD_DROPP, node->qstats.data.drop_cnt.packets);
           print_fld_size(FLD_DROPB, node->qstats.data.drop_cnt.bytes);
           print_fld_size(FLD_QLEN, node->qstats.data.qlength);
   
           if (interval > 0) {
                   pps = calc_pps(node->qstats.data.xmit_cnt.packets,
                       node->qstats_last.data.xmit_cnt.packets, interval);
                   bps = calc_rate(node->qstats.data.xmit_cnt.bytes,
                       node->qstats_last.data.xmit_cnt.bytes, interval);
   
                   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_queues(void)  print_queues(void)
 {  {
         u_int32_t n, count = 0;          uint32_t n, count, start;
         struct pf_altq_node *node = altq_root;          struct pf_altq_node *altqnode = altq_root;
           struct pfctl_queue_node *node;
   
         for (n = 0; n < dispstart; n++)          n = count = 0;
                 node = node->next_flat;          start = dispstart;
   
         for (; n < num_disp; n++) {          TAILQ_FOREACH(node, &qnodes, entries) {
                 print_queue(node);                  if (n < start) {
                 node = node->next_flat;                          n++;
                           continue;
                   }
                   print_queue_node(node);
                 end_line();                  end_line();
                 count ++;                  count++;
                   if (maxprint > 0 && count >= maxprint)
                           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)                  if (maxprint > 0 && count >= maxprint)
                         break;                          break;
         }          }

Legend:
Removed from v.1.21  
changed lines
  Added in v.1.22